home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 15 code / 3D Interface / Library / U3DDrawing.cp < prev    next >
Encoding:
Text File  |  1993-06-02  |  116.2 KB  |  4,040 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        U3DDrawing.cp
  3.  
  4.     Contains:    Adorners, classes, etc for 3D drawing effects
  5.  
  6.     Written by:    Jamie Osborne, Robin Mair, Faulkner White, Henri Lamiraux
  7.  
  8.     Copyright:    © 1992-1993 by Apple Computer, Inc.
  9.  
  10. */
  11.  
  12. /*
  13.     Some notes:
  14.             1.  This code makes your controls non-internationalized.  If you wish
  15.                 to make the controls draw with the correct system orientation
  16.                 (e.g. right to left for Hebrew), you need to check the gEnvironment
  17.                 variable and setup your drawing rects correctly.  The next Develop
  18.                 CD should have a version of this code with 
  19.                 internationalization supported.
  20.             2.  This code IS compatible with non-Color Quickdraw machines.
  21.             3.    On slower machines (anything slower than an '030), this code will
  22.                 be slow.  You should take this into account if you use this library
  23.                 in your application.  Test it out on a slower machine to see if
  24.                 it is still fast enough for your needs.  If it IS too slow, there
  25.                 are many opportunities in the code for optimization.  One example
  26.                 is removing some of the CGraphicsState objects from some of the
  27.                 routines and replacing them with CPenNormal();
  28.             4.  If you have any questions about the code, please direct them to 
  29.                 Jamie Osborne (AppleLink: JWO; Internet: jwo@applelink.apple.com).
  30. */
  31.  
  32. #ifndef __QUICKDRAW__
  33.     #include <Quickdraw.h>
  34. #endif
  35.  
  36. #ifndef __RESOURCES__
  37.     #include <Resources.h>
  38. #endif
  39.  
  40. #ifndef __GESTALTEQU__
  41.     #include <GestaltEqu.h>
  42. #endif
  43.  
  44. #include "U3DDrawing.h"
  45.  
  46. //--------------------------------------------------------------------------------------
  47. // InitU3DDrawing        Include this routine in your initialization function
  48. //--------------------------------------------------------------------------------------
  49.  
  50. #pragma segment AInit
  51. pascal void InitU3DDrawing()
  52. {
  53.     macroDontDeadStrip(TGrayBackgroundAdorner);
  54.     macroDontDeadStrip(TWhiteBackgroundAdorner);
  55.     macroDontDeadStrip(T3DGrayBackgroundAdorner);
  56.     macroDontDeadStrip(T3DFrameAdorner);
  57.     macroDontDeadStrip(T3DLineTopAdorner);
  58.     macroDontDeadStrip(T3DLineBottomAdorner);
  59.     macroDontDeadStrip(T3DLineRightAdorner);
  60.     macroDontDeadStrip(T3DLineLeftAdorner);
  61.  
  62.     macroDontDeadStrip(T3DCheckBox);
  63.     macroDontDeadStrip(T3DRadio);
  64.     macroDontDeadStrip(T3DButton);
  65.     
  66.     macroDontDeadStrip(T3DIconAdorner);
  67.     macroDontDeadStrip(TIconSuite);
  68.     macroDontDeadStrip(T3DIconButton);
  69. }
  70.  
  71. //==================================================================================== 
  72. //    •••••••••••••••••••••••••••• 3D Utility Classes •••••••••••••••••••••••••••••••••••
  73. //==================================================================================== 
  74.  
  75. //======================================================================================
  76. //    CLASS: CGraphicsState
  77. //======================================================================================
  78. //
  79. //        This class is used to save and restore the current Quickdraw graphics state.
  80. //    Create one of these objects at the beginning of a drawing method then use it to
  81. //    save and restore the state of the graphics before and after your drawing.  When
  82. //    one of these objects is created the Constructor saves off the current settings
  83. // for the fore and background colors, the pen state and the current textstyle.  It
  84. //    also does a PenNormal() call in preparation for drawing.  The destructor will just
  85. // reverse this process.  Two methods are provided that allow an explicit Save() and
  86. //    Restore() that mimic the constructor and destructor.  These method can be called 
  87. // if you want to reuse the same object during drawing.  The destructor will use the
  88. //    last values saved.
  89.  
  90. //--------------------------------------------------------------------------------------
  91. // CGraphicsState::CGraphicsState        ---<<• CONSTRUCTOR •>>---
  92. //--------------------------------------------------------------------------------------
  93. //
  94. //        Initialize the instance variables of the object by saving the current state
  95. // of some of the current port settings.
  96. //
  97. #pragma segment AUtils
  98.  
  99. CGraphicsState::CGraphicsState ()
  100. {
  101.      // • First save off the foreground and background colors and the penstate
  102.     GetIfColor ( fSaveForeColor );
  103.     GetIfBkColor ( fSaveBackColor );
  104.     GetPenState ( fSavePenState );    
  105.     CPenNormal ();
  106.     
  107.     // • Now save off the current port's textstyle information
  108.     GetPortTextStyle ( fSaveTextStyle );
  109.     
  110. } // CGraphicsState::CGraphicsState
  111.  
  112. //--------------------------------------------------------------------------------------
  113. // CGraphicsState::~CGraphicsState        ---<<• DESTRUCTOR •>>---
  114. //--------------------------------------------------------------------------------------
  115. //
  116. //        The destructor simply restores the last Save() state when it is called
  117. //
  118. #pragma segment AUtils
  119.  
  120. CGraphicsState::~CGraphicsState ()
  121. {
  122.     // • Restore the foreground and background colors and the penstate
  123.     SetIfColor ( fSaveForeColor );
  124.     SetIfBkColor ( fSaveBackColor );
  125.     SetPenState ( fSavePenState );
  126.  
  127.     // • Now restore the textstyle of the current port
  128.     SetPortTextStyle ( fSaveTextStyle );
  129.     
  130. } // CGraphicsState::~CGraphicsState
  131.  
  132. //--------------------------------------------------------------------------------------
  133. // CGraphicsState::Save
  134. //--------------------------------------------------------------------------------------
  135. //
  136. //        Save off the current graphics state so that we can restore it again
  137. // after we are done with our drawing.  Also calls PenNormal () to set the
  138. //    pen to the Quickdraw defaults.
  139. //
  140. #pragma segment AUtils
  141.  
  142. void CGraphicsState::Save ()
  143. {
  144.      // • First save off the foreground and background colors and the penstate
  145.     GetIfColor ( fSaveForeColor );
  146.     GetIfBkColor ( fSaveBackColor );
  147.     GetPenState ( fSavePenState );    
  148.     CPenNormal ();
  149.     
  150.     // • Now save off the current port's textstyle information
  151.     GetPortTextStyle ( fSaveTextStyle );
  152.     
  153. } // CGraphicsState::Save
  154.  
  155. //--------------------------------------------------------------------------------------
  156. // CGraphicsState::Restore
  157. //--------------------------------------------------------------------------------------
  158. //
  159. //        Restores the graphics state, this is typically called after doing some drawing
  160. // and after we have created an instance of this class or called the Save () method.
  161. //
  162. #pragma segment AUtils
  163.     
  164. void CGraphicsState::Restore ()
  165. {
  166.  
  167.     // • Restore the foreground and background colors and the penstate
  168.     SetIfColor ( fSaveForeColor );
  169.     SetIfBkColor ( fSaveBackColor );
  170.     SetPenState ( fSavePenState );
  171.  
  172.     // • Now restore the textstyle of the current port
  173.     SetPortTextStyle ( fSaveTextStyle );
  174.     
  175. } // CGraphicsState::Restore
  176.  
  177.  
  178. //======================================================================================
  179. // Class CDrawPerDevice
  180. //======================================================================================
  181. //    
  182.  
  183. //--------------------------------------------------------------------------------------
  184. // CDrawPerDevice::CDrawPerDevice        ---<<• CONSTRUCTOR •>>---
  185. //--------------------------------------------------------------------------------------
  186. #pragma segment AUtils
  187.  
  188. CDrawPerDevice::CDrawPerDevice()
  189. {
  190.     //    • Initialize our instance variables
  191.     fSaveClip = NULL;
  192.     fGDHandle = NULL;
  193.     
  194. } // CDrawPerDevice::CDrawPerDevice
  195.  
  196. //--------------------------------------------------------------------------------------
  197. // CDrawPerDevice::CDrawPerDevice        ---<<• CONSTRUCTOR •>>---
  198. //--------------------------------------------------------------------------------------
  199. #pragma segment AUtils
  200.  
  201. CDrawPerDevice::CDrawPerDevice ( const CRect& area )
  202. {
  203.  
  204.     //    • Initialize our fields
  205.     fSaveClip = NULL;
  206.     fGDHandle = NULL;
  207.     
  208.     //    • Save off the area passed in and convert it to global coordinates
  209.     fGlobalArea = area;
  210.     LocalToGlobal ( fGlobalArea[topLeft] );
  211.     LocalToGlobal ( fGlobalArea[botRight] );
  212.     
  213.     
  214. //    Remember the View port info
  215.     fFocus.itsViewPortInfo.clip = MakeNewRgn();
  216.     GetFocus(fFocus);
  217.     
  218.     fSaveClip = fFocus.itsViewPortInfo.clip;
  219.  
  220. //    Set a placeholder for non Color QD drawing
  221.     fDoneOldQD = FALSE;
  222. } // CDrawPerDevice::CDrawPerDevice
  223.  
  224. //--------------------------------------------------------------------------------------
  225. // CDrawPerDevice::~CDrawPerDevice        ---<<• DESTRUCTOR •>>---
  226. //--------------------------------------------------------------------------------------
  227. #pragma segment AUtils
  228.  
  229. CDrawPerDevice::~CDrawPerDevice()
  230. {
  231. //    Restore the port information
  232.     SetFocus(fFocus);
  233.  
  234. //    • If we have a saved clip then make sure that we displose of the region
  235.     fFocus.itsViewPortInfo.clip = DisposeIfRgnHandle(fFocus.itsViewPortInfo.clip);    
  236.     
  237. } // CDrawPerDevice::~CDrawPerDevice
  238.  
  239. //--------------------------------------------------------------------------------------
  240. // CDrawPerDevice::SetDrawingArea
  241. //--------------------------------------------------------------------------------------
  242. //
  243. //        This does the same thing as the constructor and can be used to reset the drawing
  244. //    area at anytime
  245. //
  246. #pragma segment AUtils
  247.  
  248. pascal void CDrawPerDevice::SetDrawingArea ( const CRect& area )
  249. {
  250.     //    • Save off the area passed in and convert it to global coordinates
  251.     fGlobalArea = area;
  252.     LocalToGlobal ( fGlobalArea[topLeft] );
  253.     LocalToGlobal ( fGlobalArea[botRight] );
  254.  
  255.     //    • Get a handle to the first device in the device list
  256.     fGDHandle = GetDeviceList ();
  257.  
  258. //    Remember the View port info
  259.     fFocus.itsViewPortInfo.clip = MakeNewRgn();
  260.     GetFocus(fFocus);
  261.  
  262.     fSaveClip = fFocus.itsViewPortInfo.clip;
  263.  
  264. } // CDrawPerDevice::SetDrawingArea
  265.  
  266. //--------------------------------------------------------------------------------------
  267. // CDrawPerDevice::NextDevice
  268. //--------------------------------------------------------------------------------------
  269. //
  270. //        This is the method that is called during the drawing process.  What it does is 
  271. //    cycle through each of the devices in the device list, returning the pixel size for
  272. //    the device, it also sets the clipping to the portion of the drawing area that is 
  273. // in need of drawing on the current device
  274.  
  275. #pragma segment AUtils
  276.  
  277. pascal Boolean CDrawPerDevice::NextDevice ( short& pixelSize )
  278. {
  279.     
  280.     Boolean foundActiveScreen = FALSE;
  281.     CRect    bounds;
  282.     CRect area;
  283.     
  284. //    Go ye not into this code if ye have not Color Quickdraw
  285.     if (!gConfiguration.hasColorQD)
  286.     {
  287.         pixelSize = 1;
  288.         foundActiveScreen = !fDoneOldQD;
  289.         fDoneOldQD = !fDoneOldQD;
  290.         return foundActiveScreen;
  291.     }
  292.     
  293.     //    • We will iterate over the device list while there are devices.  As we do this
  294.     //    are returning the pixel size of the current device and setting the clipping to
  295.     //    the area of that device that is in need of redrawing
  296.  
  297.   if (fGDHandle == NULL)
  298.     fGDHandle = GetDeviceList();
  299.   else
  300.     fGDHandle = GetNextDevice(fGDHandle);
  301.  
  302.     while ((fGDHandle != NULL) && (foundActiveScreen == FALSE))
  303.            if (TestDeviceAttribute(fGDHandle, screenDevice) && 
  304.                TestDeviceAttribute(fGDHandle, screenActive)) 
  305.         {
  306.             foundActiveScreen = TRUE;
  307.             pixelSize = (*(*fGDHandle)->gdPMap)->pixelSize;
  308.  
  309.             //    • Get the bounds of the current device
  310.             bounds = (*fGDHandle)->gdRect;
  311.             if ( SectRect ( bounds, fGlobalArea, area ) ) 
  312.             {
  313.                 //    • Convert the overlapping area to local coordinates
  314.                 GlobalToLocal ( area[topLeft] );
  315.                 GlobalToLocal ( area[botRight] );
  316.                 
  317.                 //    • Create a temporary region and convert the overlapped area to a region
  318.                 CTemporaryRegion    tempRgn;
  319.                 RectRgn ( tempRgn, area );
  320.                 
  321.                 //    • Set the temporary region to the intersection between the area and the
  322.                 // saved clipping region
  323.                 SectRgn ( tempRgn, fSaveClip, tempRgn );
  324.                 //  Clip to the visregion,too
  325.                 SectRgn(tempRgn, qd.thePort->visRgn, tempRgn);
  326.                 
  327.                 //    • Set the clip to the overlap
  328.                 SetClip ( tempRgn );
  329.                 
  330.             }
  331.             else
  332.             {
  333.                 foundActiveScreen = FALSE;
  334.                 fGDHandle = GetNextDevice(fGDHandle);
  335.             }
  336.         }
  337.         else
  338.             fGDHandle = GetNextDevice(fGDHandle);
  339.  
  340.   return foundActiveScreen;
  341.  
  342. } // CDrawPerDevice::NextDevice
  343.  
  344.  
  345. //======================================================================================
  346. // CPenNormal    - a color version of PenNormal()
  347. //======================================================================================
  348. #pragma segment AUtils
  349.  
  350. pascal void CPenNormal()
  351. {
  352.     RGBForeColor(gRGBBlack);
  353.     RGBBackColor(gRGBWhite);
  354.     PenNormal();
  355.  
  356. } // CPenNormal
  357.  
  358.  
  359.  
  360. //==================================================================================== 
  361. //    •••••••••••••••••••••••••••• 3D TView Adorners •••••••••••••••••••••••••••••••••••
  362. //==================================================================================== 
  363.  
  364. //--------------------------------------------------------------------------------------------------
  365. #pragma segment A3DOpen
  366.  
  367. pascal void TWhiteBackgroundAdorner::Initialize()
  368. {
  369.     inherited::Initialize();
  370. }
  371.  
  372.  
  373. //--------------------------------------------------------------------------------------------------
  374. #pragma segment A3DOpen
  375.  
  376. pascal void TWhiteBackgroundAdorner::IWhiteBackgroundAdorner(Boolean freeOnDeletion)
  377. {
  378.  
  379.     this->IAdorner(kWhiteBackgroundAdorner,freeOnDeletion);
  380.  
  381. } // T3DWhiteBackgroundAdorner::I3DWhiteBackgroundAdorner
  382.  
  383.  
  384. //--------------------------------------------------------------------------------------------------
  385. #pragma segment A3DRes
  386.  
  387. pascal void TWhiteBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  388. {
  389.  
  390.     CRect            qdArea;
  391.     short            pixelSize;
  392.     CGraphicsState     rememberGState;
  393.     
  394.     itsView->ViewToQDRect(area, qdArea);
  395.  
  396.     CDrawPerDevice device(qdArea);
  397.     while (device.NextDevice(pixelSize)) 
  398.     {
  399. //        Only draw us if we are on a non B & W monitor
  400.         if (pixelSize >= 4) 
  401.         {    
  402.             SetIfBkColor(gRGBWhite);
  403.             EraseRect(qdArea);
  404.         }
  405.     }    
  406. } // TWhiteBackgroundAdorner::Draw
  407.  
  408.  
  409. //--------------------------------------------------------------------------------------------------
  410. #pragma segment A3DOpen
  411.  
  412. pascal void TGrayBackgroundAdorner::Initialize()
  413. {
  414.     inherited::Initialize();
  415. }
  416.  
  417.  
  418. //--------------------------------------------------------------------------------------------------
  419. #pragma segment A3DOpen
  420.  
  421. pascal void TGrayBackgroundAdorner::IGrayBackgroundAdorner(Boolean freeOnDeletion)
  422. {
  423.  
  424.     this->IAdorner(kGrayBackgroundAdorner,freeOnDeletion);
  425.  
  426. } // T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner
  427.  
  428.  
  429. //--------------------------------------------------------------------------------------------------
  430. #pragma segment A3DRes
  431.  
  432. pascal void TGrayBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  433. {
  434.  
  435.     CRect            qdArea;
  436.     short            pixelSize;
  437.     CGraphicsState     rememberGState;
  438.     
  439.     itsView->ViewToQDRect(area, qdArea);
  440.  
  441.     CDrawPerDevice device(qdArea);
  442.     while (device.NextDevice(pixelSize)) 
  443.     {
  444.         if (pixelSize >= 4) 
  445.         {    
  446. //            Erase because we want our subviews to draw on gray
  447.             SetIfBkColor(kLightGray);
  448.             EraseRect(qdArea);
  449.         }
  450.     }    
  451. } // TGrayBackgroundAdorner::Draw
  452.  
  453.  
  454. //--------------------------------------------------------------------------------------------------
  455. #pragma segment A3DOpen
  456.  
  457. pascal void T3DGrayBackgroundAdorner::Initialize()
  458. {
  459.     inherited::Initialize();
  460. }
  461.  
  462.  
  463. //--------------------------------------------------------------------------------------------------
  464. #pragma segment A3DOpen
  465.  
  466. pascal void T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner(Boolean freeOnDeletion)
  467. {
  468.  
  469.     this->IGrayBackgroundAdorner(freeOnDeletion);
  470.  
  471. } // T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner
  472.  
  473.  
  474. //--------------------------------------------------------------------------------------------------
  475. #pragma segment A3DRes
  476.  
  477. pascal void T3DGrayBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  478. {
  479.  
  480.     CRect            qdArea, frame;
  481.     VRect            viewRect;
  482.     short            pixelSize;
  483.     CGraphicsState     rememberGState;
  484.     
  485. //    Erase the background in gray
  486.     inherited:: Draw(itsView,area);
  487.  
  488.     itsView->ViewToQDRect(area, qdArea);
  489.     itsView->GetAdornExtent(viewRect);
  490.     itsView->ViewToQDRect(viewRect, frame);
  491.  
  492.     CDrawPerDevice device(qdArea);    
  493.     while (device.NextDevice(pixelSize)) 
  494.     {
  495. //        Only draw on non- B & W
  496.         if (pixelSize >= 4) 
  497.         {
  498.             SetIfColor(gRGBWhite);
  499.             MoveTo(frame.right-1, frame.top);
  500.             LineTo(frame.left, frame.top);
  501.             LineTo(frame.left, frame.bottom);
  502.         
  503.             SetIfColor(kMediumLightGray);    
  504.             MoveTo(frame.left+1, frame.bottom-1);
  505.             LineTo(frame.right-1, frame.bottom-1);
  506.             LineTo(frame.right-1, frame.top+1);
  507.         }
  508.     }
  509.     
  510. } // T3DGrayBackgroundAdorner::Draw
  511.  
  512.  
  513. //--------------------------------------------------------------------------------------------------
  514. #pragma segment A3DOpen
  515.  
  516. pascal void T3DLineTopAdorner::Initialize()
  517. {
  518.     inherited::Initialize();
  519. }
  520.  
  521.  
  522. //--------------------------------------------------------------------------------------------------
  523. #pragma segment A3DOpen
  524.  
  525. pascal void T3DLineTopAdorner::I3DLineTopAdorner(Boolean freeOnDeletion)
  526. {
  527.  
  528.     this->IAdorner(k3DLineTopAdorner,freeOnDeletion);
  529.  
  530. } // T3DLineTopAdorner::I3DLineTopAdorner
  531.  
  532.  
  533. //--------------------------------------------------------------------------------------------------
  534. #pragma segment A3DRes
  535.  
  536. pascal void T3DLineTopAdorner::Draw(TView* itsView, const VRect& area)
  537. {
  538.  
  539.     CRect            qdArea, frame;
  540.     VRect            viewRect;
  541.     short            pixelSize;
  542.     CGraphicsState  rememberGState;
  543.     
  544.     itsView->ViewToQDRect(area, qdArea);
  545.     itsView->GetAdornExtent(viewRect);
  546.     itsView->ViewToQDRect(viewRect, frame);
  547.     
  548.     CDrawPerDevice device(qdArea);
  549.     while (device.NextDevice(pixelSize)) 
  550.     {
  551. //        Draw a gray and white line for non- B & W
  552.         if (pixelSize >= 4) 
  553.         {
  554.             SetIfColor(kMediumLightGray);    
  555.             MoveTo(frame.left, frame.top);
  556.             LineTo(frame.right, frame.top);
  557.     
  558.             SetIfColor(gRGBWhite);
  559.             MoveTo(frame.left, frame.top + 1);
  560.             LineTo(frame.right, frame.top + 1);
  561.         }
  562. //        Draw a regular black line
  563.         else
  564.         {
  565.     
  566.             PenPat(&qd.black);
  567.             MoveTo(frame.left, frame.top);
  568.             LineTo(frame.right, frame.top);
  569.         }
  570.     }
  571.  
  572. } // T3DLineTopAdorner::Draw
  573.  
  574.  
  575. //--------------------------------------------------------------------------------------------------
  576. #pragma segment A3DOpen
  577.  
  578. pascal void T3DLineBottomAdorner::Initialize()
  579. {
  580.     inherited::Initialize();
  581. }
  582.  
  583.  
  584. //--------------------------------------------------------------------------------------------------
  585. #pragma segment A3DOpen
  586.  
  587. pascal void T3DLineBottomAdorner::I3DLineBottomAdorner(Boolean freeOnDeletion)
  588. {
  589.  
  590.     this->IAdorner(k3DLineBottomAdorner,freeOnDeletion);
  591.  
  592. } // T3DLineBottomAdorner::I3DLineBottomAdorner
  593.  
  594.  
  595. //--------------------------------------------------------------------------------------------------
  596. #pragma segment A3DRes
  597.  
  598. pascal void T3DLineBottomAdorner::Draw(TView* itsView, const VRect& area)
  599. {
  600.  
  601.     CRect            qdArea, frame;
  602.     VRect            viewRect;
  603.     short            pixelSize;
  604.     CGraphicsState  rememberGState;
  605.     
  606.     itsView->ViewToQDRect(area, qdArea);
  607.     itsView->GetAdornExtent(viewRect);
  608.     itsView->ViewToQDRect(viewRect, frame);
  609.     
  610.     CDrawPerDevice device(qdArea);    
  611.     while (device.NextDevice(pixelSize)) 
  612.     {
  613. //        Draw a gray and white line for non- B & W
  614.         if (pixelSize >= 4) 
  615.         {
  616.             SetIfColor(kMediumLightGray);    
  617.             MoveTo(frame.left, frame.bottom - 1);
  618.             LineTo(frame.right, frame.bottom - 1);
  619.     
  620.             SetIfColor(gRGBWhite);
  621.             MoveTo(frame.left, frame.bottom);
  622.             LineTo(frame.right, frame.bottom);
  623.         }
  624. //        Draw a regular black line
  625.         else
  626.         {
  627.     
  628.             PenPat(&qd.black);
  629.             MoveTo(frame.left, frame.bottom - 1);
  630.             LineTo(frame.right, frame.bottom - 1);
  631.         }
  632.     }
  633.  
  634. } // T3DLineBottomAdorner::Draw
  635.  
  636. //--------------------------------------------------------------------------------------------------
  637. #pragma segment A3DOpen
  638.  
  639. pascal void T3DLineLeftAdorner::Initialize()
  640. {
  641.     inherited::Initialize();
  642. }
  643.  
  644.  
  645. //--------------------------------------------------------------------------------------------------
  646. #pragma segment A3DOpen
  647.  
  648. pascal void T3DLineLeftAdorner::I3DLineLeftAdorner(Boolean freeOnDeletion)
  649. {
  650.  
  651.     this->IAdorner(k3DLineLeftAdorner,freeOnDeletion);
  652.  
  653. } // T3DLineLeftAdorner::I3DLineLeftAdorner
  654.  
  655.  
  656. //--------------------------------------------------------------------------------------------------
  657. #pragma segment A3DRes
  658.  
  659. pascal void T3DLineLeftAdorner::Draw(TView* itsView, const VRect& area)
  660. {
  661.  
  662.     CRect            qdArea, frame;
  663.     VRect            viewRect;
  664.     short            pixelSize;
  665.     CGraphicsState  rememberGState;
  666.     
  667.     itsView->ViewToQDRect(area, qdArea);
  668.     itsView->GetAdornExtent(viewRect);
  669.     itsView->ViewToQDRect(viewRect, frame);
  670.     
  671.     CDrawPerDevice device(qdArea);
  672.     while (device.NextDevice(pixelSize)) 
  673.     {
  674. //        Draw a gray and white line for non- B & W
  675.         if (pixelSize >= 4) 
  676.         {
  677.             SetIfColor(kMediumLightGray);    
  678.             MoveTo(frame.left, frame.top);
  679.             LineTo(frame.left, frame.bottom);
  680.     
  681.             SetIfColor(gRGBWhite);
  682.             MoveTo(frame.left + 1, frame.top);
  683.             LineTo(frame.left + 1, frame.bottom);
  684.         }
  685. //        Draw a regular black line
  686.         else
  687.         {
  688.     
  689.             PenPat(&qd.black);
  690.             MoveTo(frame.left, frame.top);
  691.             LineTo(frame.left, frame.bottom);
  692.         }
  693.     }
  694.  
  695. } // T3DLineLeftAdorner::Draw
  696.  
  697. //--------------------------------------------------------------------------------------------------
  698. #pragma segment A3DOpen
  699.  
  700. pascal void T3DLineRightAdorner::Initialize()
  701. {
  702.     inherited::Initialize();
  703. }
  704.  
  705.  
  706. //--------------------------------------------------------------------------------------------------
  707. #pragma segment A3DOpen
  708.  
  709. pascal void T3DLineRightAdorner::I3DLineRightAdorner(Boolean freeOnDeletion)
  710. {
  711.  
  712.     this->IAdorner(k3DLineRightAdorner,freeOnDeletion);
  713.  
  714. } // T3DLineRightAdorner::I3DLineRightAdorner
  715.  
  716.  
  717. //--------------------------------------------------------------------------------------------------
  718. #pragma segment A3DRes
  719.  
  720. pascal void T3DLineRightAdorner::Draw(TView* itsView, const VRect& area)
  721. {
  722.  
  723.     CRect            qdArea, frame;
  724.     VRect            viewRect;
  725.     short            pixelSize;
  726.     CGraphicsState  rememberGState;
  727.     
  728.     itsView->ViewToQDRect(area, qdArea);
  729.     itsView->GetAdornExtent(viewRect);
  730.     itsView->ViewToQDRect(viewRect, frame);
  731.     
  732.     CDrawPerDevice device(qdArea);    
  733.     while (device.NextDevice(pixelSize)) 
  734.     {
  735. //        Draw a gray and white line for non- B & W
  736.         if (pixelSize >= 4) 
  737.         {
  738.             SetIfColor(kMediumLightGray);    
  739.             MoveTo(frame.right - 1, frame.top);
  740.             LineTo(frame.right -1, frame.bottom);
  741.     
  742.             SetIfColor(gRGBWhite);
  743.             MoveTo(frame.right, frame.top);
  744.             LineTo(frame.right, frame.bottom);
  745.         }
  746. //        Draw a regular black line
  747.         else
  748.         {
  749.     
  750.             PenPat(&qd.black);
  751.             MoveTo(frame.right - 1, frame.top);
  752.             LineTo(frame.right - 1, frame.bottom);
  753.         }
  754.     }
  755.  
  756. } // T3DLineRightAdorner::Draw
  757.  
  758.  
  759. //--------------------------------------------------------------------------------------------------
  760. #pragma segment A3DOpen
  761.  
  762. pascal void T3DFrameAdorner::Initialize()
  763. {
  764.     inherited::Initialize();
  765. }
  766.  
  767.  
  768. //--------------------------------------------------------------------------------------------------
  769. #pragma segment A3DOpen
  770.  
  771. pascal void T3DFrameAdorner::I3DFrameAdorner(Boolean freeOnDeletion)
  772. {
  773.  
  774.     this->IAdorner(k3DFrameAdorner,freeOnDeletion);
  775.  
  776. } // T3DFrameAdorner::I3DFrameAdorner
  777.  
  778.  
  779. //--------------------------------------------------------------------------------------------------
  780. #pragma segment A3DRes
  781.  
  782. pascal void T3DFrameAdorner::Draw(TView* itsView, const VRect& area)
  783. {
  784.  
  785.     CRect            qdArea, frame;
  786.     VRect            viewRect;
  787.     short            pixelSize;
  788.     CGraphicsState  rememberGState;
  789.  
  790.     itsView->ViewToQDRect(area, qdArea);
  791.     itsView->GetAdornExtent(viewRect);
  792.     itsView->ViewToQDRect(viewRect, frame);
  793.     
  794.     CDrawPerDevice device(qdArea);
  795.     while (device.NextDevice(pixelSize))
  796.     {
  797. //        Draw a gray and white frame with black outline
  798.         if (pixelSize >= 4) {
  799.  
  800.             SetIfColor(kMediumLightGray);
  801.             MoveTo(frame.right, frame.top);
  802.             LineTo(frame.left, frame.top);
  803.             LineTo(frame.left, frame.bottom);
  804.         
  805.             SetIfColor(gRGBWhite);    
  806.             MoveTo(frame.left +1, frame.bottom -1);
  807.             LineTo(frame.right -1, frame.bottom -1);
  808.             LineTo(frame.right -1, frame.top + 1);
  809.             
  810.             SetIfColor(gRGBBlack);    
  811.             InsetRect(frame, 1, 1);
  812.             FrameRect(frame);
  813.             InsetRect(frame, -1, -1);
  814.         }
  815. //        Draw a regular frame
  816.         else
  817.         {
  818.             PenPat(&qd.black);
  819.             InsetRect(frame, 1, 1);
  820.             FrameRect(frame);
  821.             InsetRect(frame, -1, -1);
  822.         }
  823.     }
  824.  
  825. } // T3DFrameAdorner::Draw
  826.  
  827.  
  828.  
  829. //==================================================================================== 
  830. //    ••••••••••••••••• TControl classes and auxiliary adorners •••••••••••••••••••••••
  831. //==================================================================================== 
  832.  
  833. //-------------------------------------------------------------------------------------
  834. // T3DCheckBox::Initialize
  835. //-------------------------------------------------------------------------------------
  836. #pragma segment A3DControlOpen
  837.  
  838. pascal void T3DCheckBox::Initialize ()                // OVERRIDE 
  839. {
  840.  
  841.     inherited::Initialize();
  842.     
  843.     fBackColor = kLightGray;
  844.     fForeColor = gRGBBlack;
  845.     fDrawBox = VRect(1, 0, 15, 14);        //    A standard check box is 14x14
  846.     
  847. } // T3DCheckBox::Initialize
  848.  
  849.  
  850.  
  851. //-------------------------------------------------------------------------------------
  852. // T3DCheckBox::DoPostCreate
  853. //-------------------------------------------------------------------------------------
  854. #pragma segment A3DControlOpen
  855.  
  856. pascal void T3DCheckBox::DoPostCreate (TDocument *itsDocument) // OVERRIDE 
  857. {
  858.     VRect                    theRect;
  859.     TDrawingEnvironment     *environment;
  860.     
  861.     inherited::DoPostCreate (itsDocument);
  862.     
  863. //    If we have a drawing environment, use it for drawing!
  864.     if (environment = this->GetDrawingEnvironment())
  865.     {
  866.         this->SetBackColor(environment->fBackgroundColor);
  867.         this->InstallColor(environment->fForegroundColor, FALSE);
  868.     }
  869.     this->ControlArea(theRect);
  870.  
  871. //    Center the check box vertically
  872.     long height = theRect.bottom - theRect.top;
  873.     height -= 14;
  874.     long top = height / 2;
  875.     fDrawBox.top += top;
  876.     fDrawBox.bottom += top;
  877.     
  878. } // T3DCheckBox::DoPostCreate
  879.  
  880.  
  881. //-------------------------------------------------------------------------------------
  882. // T3DCheckBox::I3DCheckBox
  883. //-------------------------------------------------------------------------------------
  884. #pragma segment A3DControlOpen
  885.  
  886. pascal void T3DCheckBox::I3DCheckBox (TView* itsSuperView, const VPoint& itsLocation,
  887.                                  const VPoint& itsSize, SizeDeterminer itsHSizeDet,
  888.                                  SizeDeterminer itsVSizeDet, const CStr255& itsLabel,
  889.                                  Boolean isTurnedOn)
  890. {
  891.     VRect                    theRect;
  892.     TDrawingEnvironment     *environment;
  893.     
  894.     this->ICheckBox (itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel, isTurnedOn);
  895.     
  896. //    If we have a drawing environment, use it for drawing!
  897.     if (environment = this->GetDrawingEnvironment())
  898.     {
  899.         this->SetBackColor(environment->fBackgroundColor);
  900.         this->InstallColor(environment->fForegroundColor, FALSE);
  901.     }
  902.     this->ControlArea(theRect);
  903.  
  904. //    Center the check box vertically
  905.     long height = theRect.bottom - theRect.top;
  906.     height -= 14;
  907.     long top = height / 2;
  908.     fDrawBox.top += top;
  909.     fDrawBox.bottom += top;
  910.     
  911.  
  912. } // T3DCheckBox::I3DCheckBox
  913.  
  914.  
  915. //-------------------------------------------------------------------------------------
  916. // T3DCheckBox::Clone
  917. //-------------------------------------------------------------------------------------
  918. #pragma segment A3DControlNonRes
  919.  
  920. pascal TObject* T3DCheckBox::Clone ()                // OVERRIDE 
  921. {
  922.  
  923.     T3DCheckBox*    aClonedCheckBox;
  924.  
  925.     aClonedCheckBox = (T3DCheckBox *)(inherited::Clone ());
  926.  
  927.     aClonedCheckBox->fBackColor = fBackColor;
  928.     aClonedCheckBox->fForeColor = fForeColor;
  929.     
  930.     return aClonedCheckBox;
  931.     
  932. } // T3DCheckBox::Clone
  933.  
  934.  
  935. //-------------------------------------------------------------------------------------
  936. // T3DCheckBox::Free
  937. //-------------------------------------------------------------------------------------
  938. #pragma segment A3DControlClose
  939.  
  940. pascal void T3DCheckBox::Free ()                    // OVERRIDE 
  941. {
  942.     inherited::Free ();
  943.     
  944. } // T3DCheckBox::Free
  945.  
  946.  
  947. //----------------------------------------------------------------------------------------
  948. // T3DCheckBox::Draw:
  949. //----------------------------------------------------------------------------------------
  950. #pragma segment A3DControlRes
  951.  
  952. pascal void T3DCheckBox::Draw (const VRect& /*area*/)    
  953. {
  954.     VRect             theRect;
  955.     CRect            qdArea;
  956.     CStr255            label;
  957.     CGraphicsState    remember;
  958.     
  959.     this->ControlArea(theRect);
  960.     this->ViewToQDRect(theRect, qdArea);
  961.  
  962.     this->DrawBox();
  963.     this->DrawCheck();
  964.     
  965.     this->GetText (label);    
  966.     CRect textBox = qdArea;
  967.  
  968. //    Move the text 3 pixels to the right of the check box
  969.     textBox.left += (short) fDrawBox.right + 3;
  970.     DrawBoxText (label, textBox, FALSE);
  971.     
  972. } // T3DCheckBox::Draw
  973.  
  974.  
  975. //-------------------------------------------------------------------------------------
  976. // T3DButton::DoMouseCommand
  977. //-------------------------------------------------------------------------------------
  978. #pragma segment A3DControlSelCommand
  979.  
  980. pascal void T3DCheckBox::DoMouseCommand(VPoint& theMouse,
  981.                                                  TToolboxEvent* ,
  982.                                                  CPoint)        // override 
  983. {
  984.     TControlTracker * aControlTracker = new TControlTracker;
  985.     aControlTracker->IControlTracker(this, theMouse);
  986.     this->PostCommand(aControlTracker);
  987. } // T3DCheckBox::DoMouseCommand
  988.  
  989. //-------------------------------------------------------------------------------------
  990. // T3DCheckBox::TrackMouse
  991. //-------------------------------------------------------------------------------------
  992. #pragma segment A3DControlSelCommand
  993.  
  994. pascal void T3DCheckBox::TrackMouse(TrackPhase aTrackPhase,
  995.                                                              VPoint& ,
  996.                                                              // anchorPoint
  997.                                                              VPoint& ,
  998.                                                              // previousPoint
  999.                                                              VPoint& nextPoint,
  1000.                                                              Boolean)                            // OVERRIDE
  1001. {
  1002.     Boolean state = false;
  1003.     
  1004.     if (!this->IsDimmed())
  1005.         switch(aTrackPhase)
  1006.         {
  1007.             case trackBegin:
  1008.                 state = fHilite;
  1009.                 this->HiliteState(TRUE, kRedraw);
  1010.                 break;
  1011.             case trackContinue:
  1012.                 if (this->ContainsMouse(nextPoint))
  1013.                     this->HiliteState(TRUE, kRedraw);
  1014.                 else
  1015.                     this->HiliteState(state, kRedraw);
  1016.                 break;
  1017.             case trackEnd:
  1018.                 if (this->ContainsMouse(nextPoint))
  1019.                 {
  1020.                     this->HiliteState(FALSE, this->IsOn());
  1021.                     this->HandleEvent(fEventNumber, this, NULL);
  1022.                 }
  1023.                 break;
  1024.         }
  1025. }    // T3DCheckBox::TrackMouse
  1026.  
  1027.  
  1028. //----------------------------------------------------------------------------------------
  1029. // T3DCheckBox::SetLongVal:
  1030. //    Override the way the control works so that we don't call the CDEF
  1031. //----------------------------------------------------------------------------------------
  1032. #pragma segment A3DControlRes
  1033.  
  1034. pascal void T3DCheckBox::SetLongVal(VCoordinate itsVal,
  1035.                                 Boolean /*redraw*/)
  1036. {
  1037.  
  1038.     itsVal = Max(fLongMin, Min(itsVal, fLongMax));
  1039.     if (itsVal != fLongVal)
  1040.     {
  1041.         fLongVal = itsVal;
  1042.         CRect tempRect;
  1043.         this->ViewToQDRect(fDrawBox, tempRect);
  1044.         InsetRect(tempRect, 2,2);
  1045.         this->InvalidateRect(tempRect);
  1046.     }
  1047. } // T3DCheckBox::SetLongVal
  1048.  
  1049.  
  1050. //----------------------------------------------------------------------------------------
  1051. // T3DCheckBox::HiliteState:
  1052. //----------------------------------------------------------------------------------------
  1053. #pragma segment A3DControlNonRes
  1054.  
  1055. pascal void T3DCheckBox::HiliteState(Boolean state,Boolean redraw)
  1056. {
  1057.     if (state != fHilite)
  1058.     {
  1059.         fHilite = state;
  1060.         if (state)                                // hilite adorner draws the hilite state
  1061.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  1062.         else
  1063.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  1064.         if (redraw)
  1065.             this->Hilite();
  1066.     }
  1067. } // T3DCheckBox::HiliteState
  1068.  
  1069.  
  1070. //----------------------------------------------------------------------------------------
  1071. // T3DCheckBox::DimState:
  1072. //----------------------------------------------------------------------------------------
  1073. #pragma segment A3DControlNonRes
  1074.  
  1075. pascal void T3DCheckBox::DimState(Boolean state,
  1076.                                Boolean redraw)
  1077. {
  1078.     if (state != fDimmed)
  1079.     {
  1080.         fDimmed = state;
  1081.         if (state)                                // dim adorner draws the dim state
  1082.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  1083.         else
  1084.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  1085.         if (redraw)
  1086.             this->DrawContents();                // Draw change immediately
  1087.     }
  1088. } // T3DCheckBox::DimState
  1089.  
  1090.  
  1091. //-------------------------------------------------------------------------------------
  1092. // T3DCheckBox::Hilite
  1093. //-------------------------------------------------------------------------------------
  1094. #pragma segment A3DControlRes
  1095.  
  1096. pascal void T3DCheckBox::Hilite ()        // OVERRIDE
  1097. {
  1098.  
  1099.     VRect                area;
  1100.     CRect                qdArea, qdBox;
  1101.     CGraphicsState        rememberGState;
  1102.     
  1103.     #if qDebug
  1104.         this->AssumeFocused ();
  1105.     #endif
  1106.     
  1107.     this->ControlArea (area);
  1108.     this->ViewToQDRect (area, qdArea);
  1109.     this->ViewToQDRect(fDrawBox, qdBox);
  1110.  
  1111.     CPenNormal();
  1112.     if (fHilite) 
  1113.     {
  1114.         InsetRect(qdBox, 2, 2);
  1115.         FrameRect(qdBox);
  1116.     }
  1117.     else
  1118.         this->DrawCheck();
  1119. } // T3DCheckBox::Hilite
  1120.  
  1121.  
  1122. //-------------------------------------------------------------------------------------
  1123. // T3DCheckBox::Dim
  1124. //-------------------------------------------------------------------------------------
  1125. #pragma segment A3DControlRes
  1126.  
  1127. pascal void T3DCheckBox::Dim ()        // OVERRIDE
  1128. {
  1129.     VRect             area;
  1130.     CRect             qdArea;
  1131.     CGraphicsState    rememberGState;
  1132.     
  1133.     this->ControlArea (area);
  1134.     area.left += fDrawBox.right;
  1135.     this->ViewToQDRect (area, qdArea);
  1136.  
  1137.     short pixelSize;
  1138.     CDrawPerDevice device(qdArea);
  1139.     while (device.NextDevice (pixelSize)) 
  1140.     {
  1141. //        If in B & W, do the standard gray pattern.  Non B & W is taken care of in
  1142. //            the DrawCheck and DrawBox routines
  1143.         if (pixelSize < 2)
  1144.         {
  1145.             #if qDebug
  1146.                 this->AssumeFocused ();
  1147.             #endif
  1148.             
  1149.             InsetRect (qdArea, 1, 1);
  1150.             
  1151.             PenPat (&qd.gray);
  1152.             PenMode (patBic);
  1153.             PaintRect (qdArea);
  1154.         }
  1155.     }
  1156. } // T3DCheckBox::Dim
  1157.  
  1158. //-------------------------------------------------------------------------------------
  1159. // T3DCheckBox::DrawBoxText
  1160. //-------------------------------------------------------------------------------------
  1161. #pragma segment A3DControlRes
  1162.  
  1163. pascal void T3DCheckBox::DrawBoxText (const CStr255& s, const CRect& box, Boolean preferOutline)
  1164. {
  1165.     FontInfo         theFontInfo;
  1166.     CRect             localBox = box;
  1167.     CRect             qdArea;
  1168.     CGraphicsState    rememberGState;
  1169.     
  1170.     CWhileOutlinePreferred setOP (preferOutline);
  1171.     
  1172.     short textHeight = MAGetFontInfo (theFontInfo);
  1173.     CPoint boxSize = localBox.GetSize ();
  1174.     
  1175. //    Center the text vertically
  1176.     localBox.top += (boxSize.v - textHeight) / 2;
  1177.     MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1178.     
  1179.     short pixelSize;
  1180.     CDrawPerDevice device(localBox);
  1181.     while (device.NextDevice (pixelSize)) 
  1182.     {
  1183.     //    If we're dimmed, draw in gray, else draw in the fore color
  1184.         if (pixelSize > 2)
  1185.         {    
  1186.             SetIfBkColor(fBackColor);
  1187.             if (this->IsDimmed())
  1188.                 SetIfColor(kMediumGray);
  1189.             else
  1190.                 SetIfColor(fForeColor);
  1191.         }
  1192.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1193.         DrawString(s);
  1194.     }
  1195.  
  1196. } // T3DCheckBox::DrawBoxText
  1197.  
  1198.  
  1199. //-------------------------------------------------------------------------------------
  1200. // T3DCheckBox::DrawBox
  1201. //-------------------------------------------------------------------------------------
  1202. #pragma segment A3DControlRes
  1203.  
  1204. pascal void T3DCheckBox::DrawBox()
  1205. {
  1206.     CRect            qdBox;
  1207.     short            pixelSize;
  1208.     CGraphicsState    rememberGState;
  1209.     
  1210.     this->ViewToQDRect(fDrawBox, qdBox);
  1211.     
  1212.     CDrawPerDevice device(qdBox);
  1213.     while (device.NextDevice (pixelSize)) 
  1214.     {
  1215. //            Draw the 3D effect if we're in non B & W
  1216.         if (pixelSize > 2) 
  1217.         {
  1218.             if (!this->IsDimmed())
  1219.             {
  1220.                 SetIfColor(gRGBWhite);    
  1221.                 MoveTo(qdBox.left+1, qdBox.bottom-1);
  1222.                 LineTo(qdBox.right-1, qdBox.bottom-1);
  1223.                 LineTo(qdBox.right-1, qdBox.top+1);
  1224.     
  1225.                 SetIfColor(kMediumLightGray);
  1226.                 MoveTo(qdBox.right, qdBox.top);
  1227.                 LineTo(qdBox.left, qdBox.top);
  1228.                 LineTo(qdBox.left, qdBox.bottom);
  1229.                 SetIfColor(fForeColor);
  1230.             }
  1231.             else
  1232.                 SetIfColor(kMediumGray);
  1233.         }
  1234.         else
  1235.             SetIfColor(gRGBBlack);
  1236.  
  1237.     //    Now draw the regular check box
  1238.         InsetRect(qdBox, 1, 1);
  1239.         FrameRect(qdBox);            
  1240.         InsetRect(qdBox, -1, -1);
  1241.     }
  1242.  
  1243. }
  1244.  
  1245.  
  1246. //-------------------------------------------------------------------------------------
  1247. // T3DCheckBox::DrawCheck
  1248. //-------------------------------------------------------------------------------------
  1249. #pragma segment A3DControlRes
  1250.  
  1251. pascal void T3DCheckBox::DrawCheck()
  1252. {
  1253.     CRect            qdBox;
  1254.     CGraphicsState    rememberGState;
  1255.     
  1256.     this->ViewToQDRect(fDrawBox, qdBox);
  1257.  
  1258.     InsetRect(qdBox, 2, 2);
  1259.     SetIfBkColor(gRGBWhite);
  1260.     EraseRect(qdBox);
  1261.  
  1262. //    Draw the check if we're on
  1263.     if (this->IsOn())
  1264.     {
  1265.         short pixelSize;
  1266.         CDrawPerDevice device(qdBox);
  1267.         while (device.NextDevice (pixelSize)) 
  1268.         {
  1269.             if (pixelSize > 2) 
  1270.                 if (this->IsDimmed())
  1271.                     SetIfColor(kMediumGray);
  1272.  
  1273.             MoveTo(qdBox.left-1, qdBox.bottom);
  1274.             LineTo(qdBox.right-1, qdBox.top);
  1275.             MoveTo(qdBox.left, qdBox.top);
  1276.             LineTo(qdBox.right, qdBox.bottom);
  1277.         }
  1278.     }
  1279. }
  1280.  
  1281.  
  1282. //-------------------------------------------------------------------------------------
  1283. // T3DCheckBox::DrawCheck
  1284. //        Override because we don't want the inherited method, which uses the CDEF
  1285. //-------------------------------------------------------------------------------------
  1286. #pragma segment A3DControlRes
  1287.  
  1288. pascal void T3DCheckBox::InstallColor(const CRGBColor& theColor,
  1289.                                    Boolean redraw)
  1290. {
  1291.     fForeColor = theColor;
  1292.     if (redraw)
  1293.         this->ForceRedraw();
  1294. }
  1295.  
  1296.  
  1297. //-------------------------------------------------------------------------------------
  1298. // T3DRadio::Initialize
  1299. //-------------------------------------------------------------------------------------
  1300. #pragma segment A3DControlOpen
  1301.  
  1302. pascal void T3DRadio::Initialize ()                // OVERRIDE 
  1303. {
  1304.  
  1305.     inherited::Initialize();
  1306.     
  1307.     fBackColor = kLightGray;
  1308.     fForeColor = gRGBBlack;
  1309.     fDrawBox = VRect(2, 0, 14, 12);        //    A radio button is 12x12
  1310.     
  1311. } // T3DRadio::Initialize
  1312.  
  1313.  
  1314.  
  1315. //-------------------------------------------------------------------------------------
  1316. // T3DRadio::DoPostCreate
  1317. //-------------------------------------------------------------------------------------
  1318. #pragma segment A3DControlOpen
  1319.  
  1320. pascal void T3DRadio::DoPostCreate (TDocument *itsDocument) // OVERRIDE 
  1321. {
  1322.     VRect                    theRect;
  1323.     TDrawingEnvironment     *environment;
  1324.     
  1325.     inherited::DoPostCreate (itsDocument);
  1326.     
  1327. //    If we have a drawing environment, use it!
  1328.     if (environment = this->GetDrawingEnvironment())
  1329.     {
  1330.         this->SetBackColor(environment->fBackgroundColor);
  1331.         this->InstallColor(environment->fForegroundColor, FALSE);
  1332.     }
  1333.     
  1334. //    Center the button vertically
  1335.     this->ControlArea(theRect);
  1336.     long height = theRect.bottom - theRect.top;
  1337.     height -= 12;
  1338.     long top = height / 2;
  1339.     fDrawBox.top += top;
  1340.     fDrawBox.bottom += top;
  1341.     
  1342. } // T3DRadio::DoPostCreate
  1343.  
  1344.  
  1345. //-------------------------------------------------------------------------------------
  1346. // T3DRadio::I3DRadio
  1347. //-------------------------------------------------------------------------------------
  1348. #pragma segment A3DControlOpen
  1349.  
  1350. pascal void T3DRadio::I3DRadio (TView* itsSuperView, const VPoint& itsLocation,
  1351.                                  const VPoint& itsSize, SizeDeterminer itsHSizeDet,
  1352.                                  SizeDeterminer itsVSizeDet, const CStr255& itsLabel,
  1353.                                  Boolean isTurnedOn)
  1354. {
  1355.     VRect                    theRect;
  1356.     TDrawingEnvironment     *environment;
  1357.     
  1358.     this->IRadio (itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel, isTurnedOn);
  1359.     
  1360. //    If we have a drawing environment, use it!
  1361.     if (environment = this->GetDrawingEnvironment())
  1362.     {
  1363.         this->SetBackColor(environment->fBackgroundColor);
  1364.         this->InstallColor(environment->fForegroundColor, FALSE);
  1365.     }
  1366.     
  1367. //    Center the button vertically
  1368.     this->ControlArea(theRect);
  1369.     long height = theRect.bottom - theRect.top;
  1370.     height -= 12;
  1371.     long top = height / 2;
  1372.     fDrawBox.top += top;
  1373.     fDrawBox.bottom += top;
  1374.     
  1375.  
  1376. } // T3DRadio::I3DRadio
  1377.  
  1378.  
  1379. //-------------------------------------------------------------------------------------
  1380. // T3DRadio::Clone
  1381. //-------------------------------------------------------------------------------------
  1382. #pragma segment A3DControlNonRes
  1383.  
  1384. pascal TObject* T3DRadio::Clone ()                // OVERRIDE 
  1385. {
  1386.  
  1387.     T3DRadio*    aClonedRadio;
  1388.  
  1389.     aClonedRadio = (T3DRadio *)(inherited::Clone ());
  1390.  
  1391.     aClonedRadio->fBackColor = fBackColor;
  1392.     aClonedRadio->fForeColor = fForeColor;
  1393.     
  1394.     return aClonedRadio;
  1395.     
  1396. } // T3DRadio::Clone
  1397.  
  1398.  
  1399. //-------------------------------------------------------------------------------------
  1400. // T3DRadio::Free
  1401. //-------------------------------------------------------------------------------------
  1402. #pragma segment A3DControlClose
  1403.  
  1404. pascal void T3DRadio::Free ()                    // OVERRIDE 
  1405. {
  1406.     inherited::Free ();
  1407.     
  1408. } // T3DRadio::Free
  1409.  
  1410.  
  1411. //-------------------------------------------------------------------------------------
  1412. // T3DRadio::Draw
  1413. //-------------------------------------------------------------------------------------
  1414. #pragma segment A3DControlRes
  1415.  
  1416. pascal void T3DRadio::Draw (const VRect& /*area*/)    
  1417. {
  1418.     VRect             theRect;
  1419.     CRect            qdArea;
  1420.     CStr255            label;
  1421.     CGraphicsState    rememberGState;
  1422.     
  1423.     this->ControlArea(theRect);
  1424.     this->ViewToQDRect(theRect, qdArea);
  1425.  
  1426.     this->DrawBox();
  1427.     this->DrawCheck();
  1428.     
  1429. //    Draw the button text 4 pixels to the right of the button
  1430.     this->GetText (label);    
  1431.     CRect textBox = qdArea;
  1432.     textBox.left += (short) fDrawBox.right + 4;
  1433.     DrawBoxText (label, textBox, FALSE);
  1434.     
  1435. } // T3DRadio::Draw
  1436.  
  1437.  
  1438. //-------------------------------------------------------------------------------------
  1439. // T3DButton::DoMouseCommand
  1440. //-------------------------------------------------------------------------------------
  1441. #pragma segment A3DControlSelCommand
  1442.  
  1443. pascal void T3DRadio::DoMouseCommand(VPoint& theMouse,
  1444.                                                  TToolboxEvent* ,
  1445.                                                  CPoint)        // override 
  1446. {
  1447.     TControlTracker * aControlTracker = new TControlTracker;
  1448.     aControlTracker->IControlTracker(this, theMouse);
  1449.     this->PostCommand(aControlTracker);
  1450. } // T3DRadio::DoMouseCommand
  1451.  
  1452. //-------------------------------------------------------------------------------------
  1453. // T3DRadio::TrackMouse
  1454. //-------------------------------------------------------------------------------------
  1455. #pragma segment A3DControlSelCommand
  1456.  
  1457. pascal void T3DRadio::TrackMouse(TrackPhase aTrackPhase,
  1458.                                                              VPoint& ,
  1459.                                                              // anchorPoint
  1460.                                                              VPoint& ,
  1461.                                                              // previousPoint
  1462.                                                              VPoint& nextPoint,
  1463.                                                              Boolean)                            // OVERRIDE
  1464. {
  1465.     Boolean state = false;
  1466.     
  1467.     if (!this->IsDimmed())
  1468.         switch(aTrackPhase)
  1469.         {
  1470.             case trackBegin:
  1471.                 state = fHilite;
  1472.                 this->HiliteState(TRUE, kRedraw);
  1473.                 break;
  1474.             case trackContinue:
  1475.                 if (this->ContainsMouse(nextPoint))
  1476.                     this->HiliteState(TRUE, kRedraw);
  1477.                 else
  1478.                     this->HiliteState(state, kRedraw);
  1479.                 break;
  1480.             case trackEnd:
  1481.                 if (this->ContainsMouse(nextPoint))
  1482.                 {
  1483.                     this->HiliteState(FALSE, this->IsOn());
  1484.                     this->HandleEvent(fEventNumber, this, NULL);
  1485.                 }
  1486.                 break;
  1487.         }
  1488. }    // T3DRadio::TrackMouse
  1489.  
  1490.  
  1491. //----------------------------------------------------------------------------------------
  1492. // T3DRadio::SetLongVal:
  1493. //    Override the way the control works so that we don't call the CDEF
  1494. //----------------------------------------------------------------------------------------
  1495. #pragma segment A3DControlRes
  1496.  
  1497. pascal void T3DRadio::SetLongVal(VCoordinate itsVal,
  1498.                                 Boolean /*redraw*/)
  1499. {
  1500.     itsVal = Max(fLongMin, Min(itsVal, fLongMax));
  1501.     if (itsVal != fLongVal)
  1502.     {
  1503.         fLongVal = itsVal;
  1504.         CRect tempRect;
  1505.         this->ViewToQDRect(fDrawBox, tempRect);
  1506.  
  1507. //        Make a region for the inside of the button to invalidate
  1508.         CTemporaryRegion    region;    
  1509.         InsetRect(tempRect, 1,1);
  1510.         OpenRgn();
  1511.         FrameOval(tempRect);
  1512.         CloseRgn(region);
  1513.         this->InvalidateRegion(region);
  1514.     }
  1515. } // T3DRadio::SetLongVal
  1516.  
  1517.  
  1518. //----------------------------------------------------------------------------------------
  1519. // T3DRadio::HiliteState:
  1520. //----------------------------------------------------------------------------------------
  1521. #pragma segment A3DControlNonRes
  1522.  
  1523. pascal void T3DRadio::HiliteState(Boolean state,Boolean redraw)
  1524. {
  1525.     if (state != fHilite)
  1526.     {
  1527.         fHilite = state;
  1528.         if (state)                                // hilite adorner draws the hilite state
  1529.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  1530.         else
  1531.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  1532.         if (redraw)
  1533.             this->Hilite();
  1534.     }
  1535. } // T3DRadio::HiliteState
  1536.  
  1537.  
  1538. //----------------------------------------------------------------------------------------
  1539. // T3DRadio::DimState:
  1540. //----------------------------------------------------------------------------------------
  1541. #pragma segment A3DControlNonRes
  1542.  
  1543. pascal void T3DRadio::DimState(Boolean state,
  1544.                                Boolean redraw)
  1545. {
  1546.     if (state != fDimmed)
  1547.     {
  1548.         fDimmed = state;
  1549.         if (state)                                // dim adorner draws the dim state
  1550.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  1551.         else
  1552.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  1553.         if (redraw)
  1554.             this->DrawContents();                // Draw change immediately
  1555.     }
  1556. } // T3DRadio::DimState
  1557.  
  1558.  
  1559. //-------------------------------------------------------------------------------------
  1560. // T3DRadio::Hilite
  1561. //-------------------------------------------------------------------------------------
  1562. #pragma segment A3DControlRes
  1563.  
  1564. pascal void T3DRadio::Hilite ()        // OVERRIDE
  1565. {
  1566.  
  1567.     VRect            area;
  1568.     CRect            qdArea, qdBox;
  1569.     CGraphicsState    rememberGState;
  1570.  
  1571.     #if qDebug
  1572.         this->AssumeFocused ();
  1573.     #endif
  1574.     
  1575.     this->ControlArea (area);
  1576.     this->ViewToQDRect (area, qdArea);
  1577.     this->ViewToQDRect(fDrawBox, qdBox);
  1578.  
  1579.     CPenNormal();
  1580.     if (fHilite) 
  1581.     {
  1582.         InsetRect(qdBox, 1, 1);
  1583.         FrameOval(qdBox);
  1584.         InsetRect(qdBox, 1,1);
  1585.  
  1586. //        Erase the content of the oval
  1587.         SetIfBkColor(fBackColor);    
  1588.         if (this->IsOn())
  1589.         {
  1590.             PenPat(&qd.white);
  1591.             FrameOval(qdBox);
  1592.         }
  1593.         else
  1594.             EraseOval(qdBox);
  1595.     }
  1596.     else
  1597.         this->DrawCheck();
  1598. } // T3DRadio::Hilite
  1599.  
  1600.  
  1601. //-------------------------------------------------------------------------------------
  1602. // T3DRadio::Dim
  1603. //-------------------------------------------------------------------------------------
  1604. #pragma segment ControlRes
  1605.  
  1606. pascal void T3DRadio::Dim ()        // OVERRIDE
  1607. {
  1608.     VRect             area;
  1609.     CRect             qdArea;
  1610.     CGraphicsState    rememberGState;
  1611.  
  1612.     this->ControlArea (area);
  1613.     area.left += fDrawBox.right;
  1614.     this->ViewToQDRect (area, qdArea);
  1615.  
  1616.     short pixelSize;
  1617.     CDrawPerDevice device(qdArea);
  1618.     while (device.NextDevice (pixelSize)) 
  1619.     {
  1620. //        Do the normal gray pattern thing if we're in B & W
  1621.         if (pixelSize < 2)
  1622.         {
  1623.             #if qDebug
  1624.                 this->AssumeFocused ();
  1625.             #endif
  1626.             
  1627.             InsetRect (qdArea, 1, 1);
  1628.             
  1629.             PenPat (&qd.gray);
  1630.             PenMode (patBic);
  1631.             PaintRect (qdArea);
  1632.         }
  1633.     }
  1634. } // T3DRadio::Dim
  1635.  
  1636. //-------------------------------------------------------------------------------------
  1637. // T3DRadio::DrawBoxText
  1638. //-------------------------------------------------------------------------------------
  1639. #pragma segment A3DControlRes
  1640.  
  1641. pascal void T3DRadio::DrawBoxText (const CStr255& s, const CRect& box, Boolean preferOutline)
  1642. {
  1643.     FontInfo         theFontInfo;
  1644.     CRect             localBox = box;
  1645.     CRect            qdArea;
  1646.     CGraphicsState    rememberGState;
  1647.     
  1648.     CWhileOutlinePreferred setOP (preferOutline);
  1649.     
  1650.     short textHeight = MAGetFontInfo (theFontInfo);
  1651.     CPoint boxSize = localBox.GetSize ();
  1652.     
  1653. //    Center the text horizontally
  1654.     localBox.top += (boxSize.v - textHeight) / 2;
  1655.     MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1656.     
  1657.     short pixelSize;
  1658.     CDrawPerDevice device(localBox);
  1659.     while (device.NextDevice (pixelSize)) 
  1660.     {
  1661.     //    If we're dimmed, draw in gray, else draw in the fore color
  1662.         if (pixelSize > 2)
  1663.         {    
  1664.             SetIfBkColor(fBackColor);
  1665.             if (this->IsDimmed())
  1666.                 //    Draw the text in gray if we can
  1667.                 SetIfColor(kMediumGray);
  1668.             else
  1669.                 SetIfColor(fForeColor);
  1670.         }
  1671.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1672.         DrawString (s);        // This would be faster if we did StringWidth and DrawChar...
  1673.     }
  1674.     
  1675. } // T3DRadio::DrawBoxText
  1676.  
  1677.  
  1678. //-------------------------------------------------------------------------------------
  1679. // T3DRadio::DrawBox
  1680. //-------------------------------------------------------------------------------------
  1681. #pragma segment A3DControlRes
  1682.  
  1683. pascal void T3DRadio::DrawBox()
  1684. {
  1685.     CRect            qdBox;
  1686.     CGraphicsState    rememberGState;
  1687.     
  1688.     this->ViewToQDRect(fDrawBox, qdBox);
  1689.  
  1690.     short pixelSize;
  1691.     CDrawPerDevice device(qdBox);
  1692.     while (device.NextDevice (pixelSize)) 
  1693.     {
  1694.         if (pixelSize > 2) 
  1695.         {
  1696.             if (this->IsDimmed())
  1697.                 SetIfColor(kMediumGray);
  1698.             else
  1699.                 SetIfColor(fForeColor);
  1700.         }
  1701.         FrameOval(qdBox);
  1702.     }
  1703. }
  1704.  
  1705.  
  1706. //-------------------------------------------------------------------------------------
  1707. // T3DRadio::DrawCheck
  1708. //        This actually draws a dot, but I wanted to keep it similar to the check box
  1709. //-------------------------------------------------------------------------------------
  1710. #pragma segment A3DControlRes
  1711.  
  1712. pascal void T3DRadio::DrawCheck()
  1713. {
  1714.     CRect            qdBox;
  1715.     short            pixelSize;
  1716.     CGraphicsState    rememberGState;
  1717.     
  1718.     this->ViewToQDRect(fDrawBox, qdBox);
  1719.  
  1720. //    First erase the oval
  1721.     InsetRect(qdBox, 1, 1);
  1722.     if (this->IsDimmed())
  1723.         SetIfBkColor(fBackColor);
  1724.     else
  1725.         SetIfBkColor(gRGBWhite);
  1726.     EraseOval(qdBox);
  1727.     InsetRect(qdBox, -1, -1);
  1728.  
  1729. //    Check to see if we're on
  1730.     if (this->IsOn())
  1731.     {
  1732.         CDrawPerDevice device(qdBox);
  1733.         while (device.NextDevice (pixelSize)) 
  1734.         {
  1735. //                This takes some pretty subtle work
  1736.             if (pixelSize > 2) 
  1737.             {
  1738.                 if (!this->IsDimmed())
  1739.                 {
  1740.                     SetIfColor(kLightGray);
  1741.                     MoveTo(qdBox.left + 9, qdBox.top + 5);
  1742.                     LineTo(qdBox.left + 9, qdBox.top + 7);
  1743.                     MoveTo(qdBox.left + 5, qdBox.top + 9);
  1744.                     LineTo(qdBox.left + 7, qdBox.top + 9);
  1745.         
  1746.                     SetIfColor(kLightGray2);
  1747.                     MoveTo(qdBox.left + 3, qdBox.top + 9);
  1748.                     LineTo(qdBox.left + 4, qdBox.top + 9);
  1749.                     MoveTo(qdBox.left + 9, qdBox.top + 3);
  1750.                     LineTo(qdBox.left + 9, qdBox.top + 4);
  1751.         
  1752.                     SetIfColor(kLightGray4);
  1753.                     MoveTo(qdBox.left + 2, qdBox.top + 9);
  1754.                     LineTo(qdBox.left + 2, qdBox.top + 8);
  1755.                     LineTo(qdBox.left + 3, qdBox.top + 8);
  1756.                     MoveTo(qdBox.left + 8, qdBox.top + 3);
  1757.                     LineTo(qdBox.left + 8, qdBox.top + 2);
  1758.                     LineTo(qdBox.left + 9, qdBox.top + 2);
  1759.         
  1760.                     SetIfColor(kMediumLightGray);
  1761.                     MoveTo(qdBox.left + 2, qdBox.top + 7);
  1762.                     LineTo(qdBox.left + 2, qdBox.top + 4);
  1763.                     LineTo(qdBox.left + 4, qdBox.top + 2);
  1764.                     LineTo(qdBox.left + 7, qdBox.top + 2);
  1765.         
  1766.                     SetIfColor(kMediumGray);
  1767.                     MoveTo(qdBox.left + 1, qdBox.top + 7);
  1768.                     LineTo(qdBox.left + 1, qdBox.top + 4);
  1769.                     LineTo(qdBox.left + 4, qdBox.top + 1);
  1770.                     LineTo(qdBox.left + 7, qdBox.top + 1);
  1771.                     MoveTo(qdBox.left + 2, qdBox.top + 2); // this is faster
  1772.                     LineTo(qdBox.left + 2, qdBox.top + 2); // than SetCPixel
  1773.                     SetIfColor(gRGBBlack);
  1774.                 }
  1775.                 else
  1776.                     SetIfColor(kMediumGray);
  1777.             }
  1778.             else
  1779.                 SetIfColor(gRGBBlack);
  1780.             InsetRect(qdBox, 3,3);
  1781.             FillOval(qdBox, &qd.black);
  1782.             InsetRect(qdBox, -3, -3);
  1783.         }    
  1784.     }
  1785. //    This is how we look when we're off
  1786.     else
  1787.     {
  1788. //        Off and dimmed takes some work, off and not dimmed takes no work
  1789.         if (!this->IsDimmed())
  1790.         {
  1791.             CDrawPerDevice device(qdBox);
  1792.             while (device.NextDevice (pixelSize)) 
  1793.             {
  1794.                 if (pixelSize > 2) 
  1795.                 {
  1796.                     SetIfColor(kLightGray);
  1797.                     MoveTo(qdBox.left + 6, qdBox.top + 2);
  1798.                     LineTo(qdBox.left + 3, qdBox.top + 5);
  1799.                     MoveTo(qdBox.left + 4, qdBox.top + 5);
  1800.                     LineTo(qdBox.left + 7, qdBox.top + 2);
  1801.                     MoveTo(qdBox.left + 3, qdBox.top + 5);
  1802.                     LineTo(qdBox.left + 3, qdBox.top + 7);
  1803.         
  1804.                     SetIfColor(kLightGray2);
  1805.                     MoveTo(qdBox.left + 3, qdBox.top + 8);
  1806.                     LineTo(qdBox.left + 4, qdBox.top + 8);
  1807.                     LineTo(qdBox.left + 4, qdBox.top + 6);
  1808.                     LineTo(qdBox.left + 6, qdBox.top + 6);
  1809.                     LineTo(qdBox.left + 6, qdBox.top + 4);
  1810.                     LineTo(qdBox.left + 7, qdBox.top + 4);
  1811.                     LineTo(qdBox.left + 7, qdBox.top + 3);
  1812.                     LineTo(qdBox.left + 8, qdBox.top + 3);
  1813.                     LineTo(qdBox.left + 8, qdBox.top + 2);
  1814.                     MoveTo(qdBox.left + 5, qdBox.top + 5);
  1815.                     LineTo(qdBox.left + 5, qdBox.top + 5);
  1816.                     MoveTo(qdBox.left + 7, qdBox.top + 5);
  1817.                     LineTo(qdBox.left + 7, qdBox.top + 5);
  1818.                     MoveTo(qdBox.left + 5, qdBox.top + 7);
  1819.                     LineTo(qdBox.left + 5, qdBox.top + 7);
  1820.         
  1821.                     SetIfColor(kLightGray4);
  1822.                     MoveTo(qdBox.left + 3, qdBox.top + 9);
  1823.                     LineTo(qdBox.left + 5, qdBox.top + 9);
  1824.                     LineTo(qdBox.left + 5, qdBox.top + 8);
  1825.                     LineTo(qdBox.left + 6, qdBox.top + 8);
  1826.                     LineTo(qdBox.left + 6, qdBox.top + 7);
  1827.                     LineTo(qdBox.left + 7, qdBox.top + 7);
  1828.                     LineTo(qdBox.left + 7, qdBox.top + 6);
  1829.                     LineTo(qdBox.left + 8, qdBox.top + 6);
  1830.                     LineTo(qdBox.left + 8, qdBox.top + 4);
  1831.         
  1832.                     SetIfColor(kMediumLightGray);
  1833.                     MoveTo(qdBox.left + 6, qdBox.top + 9);
  1834.                     LineTo(qdBox.left + 7, qdBox.top + 9);
  1835.                     LineTo(qdBox.left + 7, qdBox.top + 8);
  1836.                     LineTo(qdBox.left + 8, qdBox.top + 8);
  1837.                     LineTo(qdBox.left + 8, qdBox.top + 7);
  1838.                     LineTo(qdBox.left + 9, qdBox.top + 7);
  1839.                     LineTo(qdBox.left + 9, qdBox.top + 2);
  1840.         
  1841.                     SetIfColor(kMediumGray);
  1842.                     MoveTo(qdBox.left + 4, qdBox.top + 10);
  1843.                     LineTo(qdBox.left + 7, qdBox.top + 10);
  1844.                     MoveTo(qdBox.left + 8, qdBox.top + 9);
  1845.                     LineTo(qdBox.left + 9, qdBox.top + 9);
  1846.                     LineTo(qdBox.left + 9, qdBox.top + 8);
  1847.                     MoveTo(qdBox.left + 10, qdBox.top + 7);
  1848.                     LineTo(qdBox.left + 10, qdBox.top + 4);
  1849.         
  1850.                 }
  1851.             }
  1852.         }
  1853.     }
  1854. }
  1855.  
  1856.  
  1857. //-------------------------------------------------------------------------------------
  1858. // T3DRadio::InstallColor
  1859. //        Override because we don't want the inherited method, which uses the CDEF
  1860. //-------------------------------------------------------------------------------------
  1861. #pragma segment A3DControlRes
  1862.  
  1863. pascal void T3DRadio::InstallColor(const CRGBColor& theColor,
  1864.                                    Boolean redraw)
  1865. {
  1866.     fForeColor = theColor;
  1867.     if (redraw)
  1868.         this->ForceRedraw();
  1869. }
  1870.  
  1871.  
  1872.  
  1873. //=====================================================================================
  1874. // CLASS:    T3DButton
  1875. //    A 3D version of our old friend the Button
  1876. //=====================================================================================
  1877.  
  1878. //-------------------------------------------------------------------------------------
  1879. // T3DButton::Initialize
  1880. //-------------------------------------------------------------------------------------
  1881. #pragma segment A3DControlOpen
  1882.  
  1883. pascal void T3DButton::Initialize ()                // OVERRIDE 
  1884. {
  1885.  
  1886.     inherited::Initialize();
  1887.     
  1888.     f3DAdorner = NULL;
  1889.     fHilitedTextColor = gRGBBlack;
  1890.  
  1891. } // T3DButton::Initialize
  1892.  
  1893.  
  1894. //-------------------------------------------------------------------------------------
  1895. // T3DButton::DoPostCreate
  1896. //-------------------------------------------------------------------------------------
  1897. #pragma segment A3DControlOpen
  1898.  
  1899. pascal void T3DButton::DoPostCreate (TDocument *itsDocument) // OVERRIDE 
  1900. {
  1901.  
  1902.     inherited::DoPostCreate (itsDocument);
  1903.     
  1904.     if (f3DAdorner == NULL)
  1905.         this->CreateButtonAdorner ();
  1906.         
  1907. } // T3DButton::DoPostCreate
  1908.  
  1909.  
  1910. //-------------------------------------------------------------------------------------
  1911. // T3DButton::I3DButton
  1912. //-------------------------------------------------------------------------------------
  1913. #pragma segment A3DControlOpen
  1914.  
  1915. pascal void T3DButton::I3DButton (TView* itsSuperView,  const VPoint& itsLocation,
  1916.                                                            const VPoint& itsSize,
  1917.                                                            SizeDeterminer itsHSizeDet,
  1918.                                                            SizeDeterminer itsVSizeDet,
  1919.                                                          const CStr255& itsLabel)
  1920. {
  1921.  
  1922.     this->IButton(itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel);
  1923.     
  1924.     //    • If we are being built procedurally then build the adorner
  1925.     if (f3DAdorner == NULL)
  1926.         this->CreateButtonAdorner ();
  1927.  
  1928. } // T3DButton::I3DButton
  1929.  
  1930. //-------------------------------------------------------------------------------------
  1931. // T3DButton::Clone
  1932. //-------------------------------------------------------------------------------------
  1933. #pragma segment A3DControlNonRes
  1934.  
  1935. pascal TObject* T3DButton::Clone ()                // OVERRIDE 
  1936. {
  1937.     T3DButton*    aClonedButton;
  1938.  
  1939.     aClonedButton = (T3DButton *)(inherited::Clone ());
  1940.     aClonedButton->fHilitedTextColor = fHilitedTextColor;
  1941.     aClonedButton->CreateButtonAdorner();
  1942.     
  1943.     return aClonedButton;
  1944.     
  1945. } // T3DButton::Clone
  1946.  
  1947. //-------------------------------------------------------------------------------------
  1948. // T3DButton::Free
  1949. //-------------------------------------------------------------------------------------
  1950. #pragma segment A3DControlClose
  1951.  
  1952. pascal void T3DButton::Free ()                    // OVERRIDE 
  1953. {
  1954.     inherited::Free ();
  1955.     
  1956. } // T3DButton::Free
  1957.  
  1958. //-------------------------------------------------------------------------------------
  1959. // T3DButton::DoMouseCommand
  1960. //-------------------------------------------------------------------------------------
  1961. pascal void T3DButton::DoMouseCommand(VPoint& theMouse,
  1962.                                                  TToolboxEvent* ,
  1963.                                                  CPoint)        // override 
  1964. {
  1965.     TControlTracker * aControlTracker = new TControlTracker;
  1966.     aControlTracker->IControlTracker(this, theMouse);
  1967.     this->PostCommand(aControlTracker);
  1968. } // TControl::DoMouseCommand
  1969.  
  1970. //-------------------------------------------------------------------------------------
  1971. // T3DButton::TrackMouse
  1972. //-------------------------------------------------------------------------------------
  1973. #pragma segment A3DControlSelCommand
  1974.  
  1975. pascal void T3DButton::TrackMouse(TrackPhase aTrackPhase,
  1976.                                                              VPoint& ,
  1977.                                                              // anchorPoint
  1978.                                                              VPoint& ,
  1979.                                                              // previousPoint
  1980.                                                              VPoint& nextPoint,
  1981.                                                              Boolean)                            // OVERRIDE
  1982. {
  1983.     Boolean state = false;
  1984.  
  1985.     if (!this->IsDimmed())    
  1986.         switch(aTrackPhase)
  1987.         {
  1988.             case trackBegin:
  1989.                 state = fHilite;
  1990.                 this->HiliteState(TRUE, kRedraw);
  1991.                 break;
  1992.             case trackContinue:
  1993.                 if (this->ContainsMouse(nextPoint))
  1994.                     this->HiliteState(TRUE, kRedraw);
  1995.                 else
  1996.                     this->HiliteState(state, kRedraw);
  1997.                 break;
  1998.             case trackEnd:
  1999.                 if (this->ContainsMouse(nextPoint))
  2000.                 {
  2001.                     this->HiliteState(FALSE, kRedraw);
  2002.                     this->HandleEvent(fEventNumber, this, NULL);
  2003.                 }
  2004.                 break;
  2005.         }
  2006. }    // T3DButton::TrackMouse
  2007.  
  2008. //----------------------------------------------------------------------------------------
  2009. // T3DButton::HiliteState:
  2010. //----------------------------------------------------------------------------------------
  2011. #pragma segment A3DControlNonRes
  2012.  
  2013. pascal void T3DButton::HiliteState(Boolean state,Boolean redraw)
  2014. {
  2015.     if (state != fHilite)
  2016.     {
  2017.         fHilite = state;
  2018.         if (state)                                // hilite adorner draws the hilite state
  2019.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  2020.         else
  2021.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  2022.         if (redraw && this->IsDrawable())
  2023.             this->Hilite();
  2024.     }
  2025. } // T3DButton::HiliteState
  2026.  
  2027.  
  2028. //----------------------------------------------------------------------------------------
  2029. // T3DButton::DimState:
  2030. //----------------------------------------------------------------------------------------
  2031. #pragma segment A3DControlNonRes
  2032.  
  2033. pascal void T3DButton::DimState(Boolean state,
  2034.                                Boolean redraw)
  2035. {
  2036.     if (state != fDimmed)
  2037.     {
  2038.         fDimmed = state;
  2039.         if (state)                                // dim adorner draws the dim state
  2040.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  2041.         else
  2042.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  2043.         if (redraw)
  2044.             this->DrawContents();                // Draw change immediately
  2045.     }
  2046. } // T3DButton::DimState
  2047.  
  2048. //-------------------------------------------------------------------------------------
  2049. // T3DButton::CreateButtonAdorner
  2050. //-------------------------------------------------------------------------------------
  2051. #pragma segment A3DControlOpen
  2052.  
  2053. pascal void T3DButton::CreateButtonAdorner ()
  2054. {
  2055.     
  2056.     // •    Add the Button Adorner
  2057.     T3DTextButtonAdorner* adorner = new T3DTextButtonAdorner;
  2058.     adorner->I3DTextButtonAdorner (kFreeOnDeletion);
  2059.     f3DAdorner = adorner;
  2060.     
  2061.     this->AddAdorner (adorner, kAdornFirst, kDontInvalidate);
  2062.     
  2063. } // T3DButton::CreateButtonAdorner
  2064.  
  2065. //-------------------------------------------------------------------------------------
  2066. // T3DButton::DrawBoxText
  2067. //-------------------------------------------------------------------------------------
  2068. #pragma segment A3DControlRes
  2069.  
  2070. pascal void T3DButton::DrawBoxText (    const CStr255& s,
  2071.                                                              const CRect& box,
  2072.                                                              Boolean preferOutline)
  2073. {
  2074.  
  2075.     FontInfo     theFontInfo;
  2076.     CRect         qdArea, localBox = box;
  2077.     CGraphicsState    remember;
  2078.     
  2079.     CWhileOutlinePreferred setOP (preferOutline);
  2080.     
  2081.     short textHeight = MAGetFontInfo (theFontInfo);
  2082.     CPoint boxSize = localBox.GetSize ();
  2083.     
  2084. //    Center the text in the button
  2085.     localBox.left += (boxSize.h - StringWidth (s)) / 2;
  2086.     localBox.top += (boxSize.v - textHeight) / 2;
  2087.     
  2088.     this->ViewToQDRect (localBox, qdArea);
  2089.     short    pixelSize;
  2090.     CDrawPerDevice device(qdArea);
  2091.     while (device.NextDevice (pixelSize)) 
  2092.     {
  2093.         if (pixelSize >= 4)
  2094.         {
  2095.         //    If we're non B & W and we're dimmed, draw in gray text
  2096.             if (this->IsDimmed())
  2097.                 SetIfColor(kMediumGray);
  2098.         //    If we're hilited, use the hilite text color
  2099.             else if (fHilite)
  2100.                 SetIfColor(fHilitedTextColor);
  2101.         }
  2102.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  2103.         DrawString (s);
  2104.     }
  2105.  
  2106. } // T3DButton::DrawBoxText
  2107.  
  2108. //-------------------------------------------------------------------------------------
  2109. // T3DButton::Draw
  2110. //-------------------------------------------------------------------------------------
  2111. #pragma segment A3DControlRes
  2112.  
  2113. pascal void T3DButton::Draw (const VRect& /*area*/)        // OVERRIDE 
  2114. {
  2115.  
  2116.     VRect         theRect;
  2117.     CRect        qdArea;
  2118.     CStr255        label;
  2119.     
  2120.     this->ControlArea (theRect);
  2121.     this->ViewToQDRect (theRect, qdArea);
  2122.     
  2123.     this->GetText (label);
  2124.             
  2125. //    Just draw the text.  The adorner takes care of the 3D stuff
  2126.     DrawBoxText (label, qdArea, FALSE);
  2127.     
  2128. } // T3DButton::Draw
  2129.  
  2130. //-------------------------------------------------------------------------------------
  2131. // T3DButton::Hilite
  2132. //-------------------------------------------------------------------------------------
  2133. #pragma segment ControlRes
  2134.  
  2135. pascal void T3DButton::Hilite ()        // OVERRIDE
  2136. {
  2137.  
  2138.     VRect            area;
  2139.     CRect            qdArea;
  2140.     CGraphicsState    rememberGState;
  2141.     
  2142.     #if qDebug
  2143.         this->AssumeFocused ();
  2144.     #endif
  2145.     
  2146.     this->ControlArea (area);
  2147.     this->ViewToQDRect (area, qdArea);
  2148.  
  2149.     short    pixelSize;
  2150.     CDrawPerDevice device(qdArea);
  2151. //    We use some funky logic here because of the way the 3d adorner works.
  2152. //  For 4, 8 and above, we draw one way.  Otherwise we draw another way
  2153. //    See the adorner code for more info
  2154.     while (device.NextDevice (pixelSize)) 
  2155.     {
  2156.         if (pixelSize < 4)
  2157.         {
  2158. //            We need to draw the text BEFORE the adorner if we're B & W
  2159.             if (fHilite)
  2160.             {
  2161.                 this->Draw (area);
  2162.                 f3DAdorner->Draw (this, area);
  2163.             }
  2164.             else
  2165.             {
  2166.                 f3DAdorner->Draw(this, area);
  2167.                 this->Draw(area);
  2168.             }
  2169.         }
  2170.         else
  2171.         {
  2172. //            We need to draw the text AFTER the adorner for better than B & W
  2173.             f3DAdorner->Draw(this, area);
  2174.             this->Draw(area);
  2175.         }
  2176.     }
  2177. } // T3DButton::Hilite
  2178.  
  2179. //-------------------------------------------------------------------------------------
  2180. // T3DButton::Dim
  2181. //-------------------------------------------------------------------------------------
  2182. #pragma segment A3DControlRes
  2183.  
  2184. pascal void T3DButton::Dim ()        // OVERRIDE
  2185. {
  2186.  
  2187.     VRect            area;
  2188.     CRect            qdArea;
  2189.     CGraphicsState     rememberGState;    
  2190.     
  2191.     #if qDebug
  2192.         this->AssumeFocused ();
  2193.     #endif
  2194.     
  2195.     this->ControlArea (area);
  2196.     this->ViewToQDRect (area, qdArea);
  2197.     InsetRect (qdArea, 1, 1);
  2198.     
  2199.     short pixelSize;
  2200.     CDrawPerDevice device(qdArea);
  2201.     while (device.NextDevice (pixelSize)) 
  2202.     {
  2203. //        The old fashioned way is to use a gray pattern to dim
  2204.         if (pixelSize < 2)
  2205.         {
  2206.             #if qDebug
  2207.                 this->AssumeFocused ();
  2208.             #endif
  2209.             
  2210.             InsetRect (qdArea, 1, 1);
  2211.             
  2212.             PenPat (&qd.gray);
  2213.             PenMode (patBic);
  2214.             PaintRect (qdArea);
  2215.         }
  2216.     }
  2217.  
  2218. } // T3DButton::Dim
  2219.  
  2220.  
  2221. //=====================================================================================
  2222. // T3DTextButtonAdorner
  2223. //        This is an auxiliary adorner for T3DButtons
  2224. //=====================================================================================
  2225.  
  2226. //-------------------------------------------------------------------------------------
  2227. // T3DTextButtonAdorner::I3DTextButtonAdorner
  2228. //-------------------------------------------------------------------------------------
  2229. #pragma segment A3DControlOpen
  2230.  
  2231. pascal void T3DTextButtonAdorner::I3DTextButtonAdorner (    Boolean freeOnDeletion)
  2232. {
  2233.     //    • Call our superclass to complete initialization
  2234.     this->IAdorner (k3DTextButtonAdorner,freeOnDeletion);
  2235.     
  2236. } // T3DTextButtonAdorner::I3DTextButtonAdorner
  2237.  
  2238. //=====================================================================================
  2239. // •• DRAWING
  2240. //-------------------------------------------------------------------------------------
  2241. // T3DTextButtonAdorner::Draw
  2242. //-------------------------------------------------------------------------------------
  2243. //
  2244. //    This overridden draw method handles the drawing of the buttons border and then
  2245. //    branches to the appropriate appropriate method to draw the buttons contents, based 
  2246. //    on the bit depth of the device being drawn to.  Currently this method supports 1, 4,
  2247. //    and 8 bit or more devices.
  2248.  
  2249. #pragma segment A3DControlRes
  2250.  
  2251. pascal void T3DTextButtonAdorner::Draw (    TView* itsView, 
  2252.                                                 const VRect& /*area*/)
  2253. {
  2254.  
  2255.     VRect                theRect;
  2256.     CRect                qdArea;
  2257.     short                pixelSize;
  2258.     CRGBColor            color;
  2259.     
  2260.     //    • Instantiate a stack based object that saves our graphic state
  2261.     CGraphicsState aGraphicsState;
  2262.     
  2263.     //    •    Coerce the view to a control and then get its QD area
  2264.     TControl* theControl = (TControl*)itsView;    
  2265.     theControl->ControlArea (theRect);
  2266.     theControl->ViewToQDRect (theRect, qdArea);
  2267.         
  2268.     //    • Instantiate the stack based object that handles the per device clipping
  2269.     //    the area is passed in so that the object can do clipping from it
  2270.     CDrawPerDevice device (qdArea);
  2271.     
  2272.     //    • We will cycle through all of the devices, drawing will be handle based on
  2273.     //    the pixel size for each device
  2274.     while (device.NextDevice (pixelSize)) 
  2275.     {
  2276.         
  2277.         //    • Draw the button with full colors         
  2278.         if (pixelSize >= 8) 
  2279.         {
  2280.             //    • First step is to setup the appropriate gray fill color
  2281.             if (theControl->fHilite)
  2282.                 color = kMediumGray;
  2283.             else if (((TButton *)itsView)->IsDimmed())
  2284.                 color = kLightGray;
  2285.             else
  2286.                 color = kLightGray2;
  2287.         
  2288.             //    • Fill the round rect with the color
  2289.             SetIfColor (color);
  2290.             PaintRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2291.  
  2292.             //    • Frame button with a black border or gray if it's dimmed
  2293.             if (((TButton *)itsView)->IsDimmed())
  2294.                 SetIfColor(kMediumGray);
  2295.             else
  2296.                 SetIfColor (gRGBBlack);
  2297.             this->Frame (qdArea);
  2298.             
  2299.             //    • Inset the area in preparartion for the drawing of the buttons content
  2300.             InsetRect (qdArea, 1, 1);
  2301.         
  2302.             //    • Draw the button assuming 8 bit or better color
  2303.             //         But don't draw any 3D if we're dimmed
  2304.             if (!((TButton *)itsView)->IsDimmed())
  2305.                 this->Draw8Bit (qdArea, theControl->fHilite);
  2306.             
  2307.         }
  2308.         else if (pixelSize == 4)    //    • Draw with only 16 colors
  2309.         {
  2310.         
  2311.             //    • First step is to setup the appropriate gray fill color
  2312.             if (theControl->fHilite)
  2313.                 SetRGBColor (color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2314.             else if (((TButton *)itsView)->IsDimmed())
  2315.                 color = kLightGray;
  2316.             else
  2317.                 SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2318.         
  2319.             //    • Fill the round rect with the color
  2320.             SetIfColor (color);
  2321.             PaintRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2322.  
  2323.             //    • Frame button with a black border or gray if we're dimmed
  2324.             if (((TButton *)itsView)->IsDimmed())
  2325.                 SetIfColor(kMediumGray);
  2326.             else
  2327.                 SetIfColor (gRGBBlack);
  2328.             this->Frame (qdArea);
  2329.             
  2330.             //    • Inset the area in preparartion for the drawing of the buttons content
  2331.             InsetRect (qdArea, 1, 1);
  2332.         
  2333.             //    • For now we will draw the 1 bit style for 4 bit, but this should be
  2334.             //    replaced with a 4 bit algorithm which will give you 3 shades of gray
  2335.             //         But don't draw any 3D if we're dimmed
  2336.             if (!((TButton *)itsView)->IsDimmed())
  2337.                 this->Draw4Bit (qdArea, theControl->fHilite);
  2338.             
  2339.         }            
  2340.         else if (pixelSize < 4)    //    • Draw with 4 colors or less (no grays)
  2341.         {
  2342.             //    • We are hiliting so we need to invert the whole thing
  2343.             if  (theControl->fHilite) 
  2344.             {
  2345.                 //    • First we paint the inside white
  2346.                 InvertRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2347.     
  2348.                 //    • Frame button with a black border 
  2349.                 SetIfColor (gRGBBlack);
  2350.                 this->Frame (qdArea);
  2351.             }    
  2352.             else
  2353.             {
  2354.                 //    • First we erase the entire area
  2355.                 SetIfBkColor (gRGBWhite);
  2356.                 EraseRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2357.     
  2358.                 //    • Frame button with a black border 
  2359.                 SetIfColor (gRGBBlack);
  2360.                 this->Frame (qdArea);
  2361.             }
  2362.         }            
  2363.     }
  2364.         
  2365. } // T3DTextButtonAdorner::Draw
  2366.  
  2367. //=====================================================================================
  2368. // •• PRIVATE DRAWING
  2369. //-------------------------------------------------------------------------------------
  2370. // T3DTextButtonAdorner::Draw8Bit
  2371. //-------------------------------------------------------------------------------------
  2372. #pragma segment A3DControlRes
  2373.  
  2374. pascal void T3DTextButtonAdorner::Draw8Bit (const CRect& rect,
  2375.                                                     Boolean hilite)
  2376. {
  2377.     CRect             insetArea;
  2378.     CRect             controlArea;
  2379.     CRGBColor         color;
  2380.     CRGBColor         light;
  2381.     CRGBColor         dark;
  2382.  
  2383.     //    • Make a copy of the rect passed in
  2384.     controlArea = rect;
  2385.     
  2386.     //    • Save off the area passed in
  2387.     insetArea = rect;
  2388.  
  2389.     //    • Draw the hilited button
  2390.     if (hilite) 
  2391.     {    
  2392.  
  2393.         //    • Outside edge of left top shadow
  2394.         SetRGBColor (color, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2395.         SetIfColor (color);
  2396.         MoveTo (controlArea.left, controlArea.bottom - 3);
  2397.         LineTo (controlArea.left, controlArea.top + 2);
  2398.         MoveTo (controlArea.left + 2, controlArea.top);
  2399.         LineTo (controlArea.right - 3, controlArea.top);
  2400.  
  2401.         //    • Outside edge of bottom right shadow
  2402.         SetRGBColor (color, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3);
  2403.         SetIfColor (color);
  2404.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2405.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2406.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2407.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2408.         
  2409.         //    • Inset our rectangle as we move to the next level
  2410.         InsetRect (controlArea, 1, 1);
  2411.         
  2412.         //    • Inside edge of left top shadow
  2413.         SetRGBColor (color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2414.         SetIfColor (color);
  2415.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2416.         LineTo (controlArea.left, controlArea.top + 1);
  2417.         MoveTo (controlArea.left + 1, controlArea.top);
  2418.         LineTo (controlArea.right - 2, controlArea.top);
  2419.  
  2420.         //    • Inside edge of bottom right shadow
  2421.         color = kMediumLightGray;
  2422.         SetIfColor (color);
  2423.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2424.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2425.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2426.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2427.         
  2428.         //    •• Now draw the corners 
  2429.         //    •    TopLeft 1
  2430.         SetRGBColor (light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2431.         SetRGBColor (dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2432.         this->TopLeftCorner (insetArea, light, dark, hilite);
  2433.         
  2434.         //    • TopRight 2
  2435.         SetRGBColor (light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2436.         SetRGBColor (dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2437.         this->TopRightCorner (insetArea, light, dark, hilite);
  2438.         
  2439.         //    • BotLeft 3
  2440.         //    • Colors same as previous corner
  2441.         this->BotLeftCorner (insetArea, light, dark, hilite);
  2442.         
  2443.         //    • BotRight 4
  2444.         SetRGBColor (light, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3);
  2445.         dark = kMediumLightGray;
  2446.         this->BotRightCorner (insetArea, light, dark, hilite);
  2447.         
  2448.     }
  2449.     else //    • Draw the unhilited button
  2450.     {
  2451.         
  2452.         //    • Outside edge of bottom right shadow
  2453.         SetRGBColor (color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2454.         SetIfColor (color);
  2455.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2456.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2457.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2458.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2459.         
  2460.         //    • Inset our rectangle as we move to the next level
  2461.         InsetRect (controlArea, 1, 1);
  2462.         
  2463.         //    • Light on edge of button - light source edge
  2464.         SetIfColor (gRGBWhite);
  2465.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2466.         LineTo (controlArea.left, controlArea.top + 1);
  2467.         MoveTo (controlArea.left + 1, controlArea.top);
  2468.         LineTo (controlArea.right - 2, controlArea.top);
  2469.  
  2470.         //    • Inside edge of bottom right shadow
  2471.         color = kMediumGray;
  2472.         SetIfColor (color);
  2473.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2474.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2475.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2476.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2477.         
  2478.         //    •• Now draw the corners 
  2479.         //    •    TopLeft 1
  2480.         this->TopLeftCorner (insetArea, gRGBWhite, gRGBWhite, hilite);
  2481.         
  2482.         //    • TopRight 2
  2483.         light = kLightGray4;
  2484.         this->TopRightCorner (insetArea, light, light, hilite);
  2485.         
  2486.         //    • BotLeft 3
  2487.         //    • Colors same as previous corner
  2488.         this->BotLeftCorner (insetArea, light, light, hilite);
  2489.         
  2490.         //    • BotRight 4
  2491.         light = kMediumGray;
  2492.         SetRGBColor (dark, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2493.         this->BotRightCorner (insetArea, light, dark, hilite);
  2494.         
  2495.     }
  2496.  
  2497.  
  2498. } // T3DTextButtonAdorner::Draw8Bit
  2499.  
  2500. //-------------------------------------------------------------------------------------
  2501. // T3DTextButtonAdorner::Draw4Bit
  2502. //-------------------------------------------------------------------------------------
  2503. #pragma segment A3DControlRes
  2504.  
  2505. pascal void T3DTextButtonAdorner::Draw4Bit (const CRect& rect,
  2506.                                                     Boolean hilite)
  2507. {
  2508.     CRect             insetArea;
  2509.     CRect             controlArea;
  2510.     CRGBColor         color;
  2511.     CRGBColor         light;
  2512.     CRGBColor         dark;
  2513.  
  2514.     //    • Make a copy of the rect passed in
  2515.     controlArea = rect;
  2516.     
  2517.     //    • Save off the area passed in
  2518.     insetArea = rect;
  2519.  
  2520.     //    • Draw the hilited button
  2521.     if (hilite) 
  2522.     {    
  2523.  
  2524.         //    • Outside edge of left top shadow
  2525.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2526.         SetIfColor (color);
  2527.         MoveTo (controlArea.left, controlArea.bottom - 3);
  2528.         LineTo (controlArea.left, controlArea.top + 2);
  2529.         MoveTo (controlArea.left + 2, controlArea.top);
  2530.         LineTo (controlArea.right - 3, controlArea.top);
  2531.  
  2532.         //    • Outside edge of bottom right shadow
  2533.         SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2534.         SetIfColor (color);
  2535.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2536.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2537.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2538.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2539.         
  2540.         //    • Inset our rectangle as we move to the next level
  2541.         InsetRect (controlArea, 1, 1);
  2542.         
  2543.         //    • Inside edge of left top shadow
  2544.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2545.         SetIfColor (color);
  2546.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2547.         LineTo (controlArea.left, controlArea.top + 1);
  2548.         MoveTo (controlArea.left + 1, controlArea.top);
  2549.         LineTo (controlArea.right - 2, controlArea.top);
  2550.  
  2551.         //    • Inside edge of bottom right shadow
  2552.         SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2553.         SetIfColor (color);
  2554.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2555.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2556.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2557.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2558.         
  2559.         //    •• Now draw the corners 
  2560.         //    •    TopLeft 1
  2561.         SetRGBColor (light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2562.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2563.         this->TopLeftCorner (insetArea, light, dark, hilite);
  2564.         
  2565.         //    • TopRight 2
  2566.         SetRGBColor (light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2567.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2568.         this->TopRightCorner (insetArea, light, dark, hilite);
  2569.         
  2570.         //    • BotLeft 3
  2571.         //    • Colors same as previous corner
  2572.         this->BotLeftCorner (insetArea, light, dark, hilite);
  2573.         
  2574.         //    • BotRight 4
  2575.         SetRGBColor (light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2576.         SetRGBColor (dark, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2577.         this->BotRightCorner (insetArea, light, dark, hilite);
  2578.         
  2579.     }
  2580.     else //    • Draw the unhilited button
  2581.     {
  2582.         
  2583.         //    • Outside edge of bottom right shadow
  2584.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2585.         SetIfColor (color);
  2586.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2587.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2588.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2589.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2590.         
  2591.         //    • Inset our rectangle as we move to the next level
  2592.         InsetRect (controlArea, 1, 1);
  2593.         
  2594.         //    • Light on edge of button - light source edge
  2595.         SetIfColor (gRGBWhite);
  2596.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2597.         LineTo (controlArea.left, controlArea.top + 1);
  2598.         MoveTo (controlArea.left + 1, controlArea.top);
  2599.         LineTo (controlArea.right - 2, controlArea.top);
  2600.  
  2601.         //    • Inside edge of bottom right shadow
  2602.         SetRGBColor (color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2603.         SetIfColor (color);
  2604.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2605.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2606.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2607.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2608.         
  2609.         //    •• Now draw the corners 
  2610.         //    •    TopLeft 1
  2611.         this->TopLeftCorner (insetArea, gRGBWhite, gRGBWhite, hilite);
  2612.         
  2613.         //    • TopRight 2
  2614.         SetRGBColor (light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2615.         this->TopRightCorner (insetArea, light, light, hilite);
  2616.         
  2617.         //    • BotLeft 3
  2618.         //    • Colors same as previous corner
  2619.         this->BotLeftCorner (insetArea, light, light, hilite);
  2620.         
  2621.         //    • BotRight 4
  2622.         SetRGBColor (light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2623.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2624.         this->BotRightCorner (insetArea, light, dark, hilite);
  2625.         
  2626.     }
  2627.  
  2628.  
  2629. } // T3DTextButtonAdorner::Draw4Bit
  2630.  
  2631. //-------------------------------------------------------------------------------------
  2632. // T3DTextButtonAdorner::Draw1Bit
  2633. //    This routine is actually not called
  2634. //-------------------------------------------------------------------------------------
  2635. #pragma segment A3DControlRes
  2636.  
  2637. pascal void T3DTextButtonAdorner::Draw1Bit (    const CRect& /*rect */,
  2638.                                                         Boolean /*hilite*/)
  2639. {
  2640. //    We don't actually use this now
  2641.  
  2642. } // T3DTextButtonAdorner::Draw1Bit
  2643.  
  2644. //=====================================================================================
  2645. // •• BUTTON FRAME
  2646. //-------------------------------------------------------------------------------------
  2647. // T3DTextButtonAdorner::Frame
  2648. //-------------------------------------------------------------------------------------
  2649. #pragma segment A3DControlRes
  2650.  
  2651. pascal void T3DTextButtonAdorner::Frame (const CRect& rect)
  2652. {
  2653.     //    •    Draw the frame around the button this never changes
  2654.     FrameRoundRect (rect, kOvalWidth, kOvalHeight);
  2655.  
  2656. } // T3DTextButtonAdorner::Frame
  2657.  
  2658. //=====================================================================================
  2659. // •• CORNER DRAWING
  2660. //-------------------------------------------------------------------------------------
  2661. // T3DTextButtonAdorner::TopLeftCorner
  2662. //-------------------------------------------------------------------------------------
  2663. #pragma segment A3DControlRes
  2664.  
  2665. pascal void T3DTextButtonAdorner::TopLeftCorner (const CRect& rect,
  2666.                                                             const CRGBColor light,
  2667.                                                             const CRGBColor dark,
  2668.                                                             Boolean hilite )
  2669. {
  2670.     if (hilite)
  2671.     {
  2672.         //    • Set the outer corner pixel
  2673.         SetIfColor(dark);
  2674.         MoveTo(rect.left + 1, rect.top + 1);
  2675.         LineTo(rect.left + 1, rect.top + 1);
  2676.         
  2677.         //    • Set the inner corner pixel
  2678.         SetIfColor(light);
  2679.         MoveTo(rect.left + 2, rect.top + 2);
  2680.         LineTo(rect.left + 2, rect.top + 2);
  2681.     }
  2682.     else
  2683.     {
  2684.         //    • Set the outer corner pixel
  2685.         SetIfColor(light);
  2686.         MoveTo(rect.left + 1, rect.top + 1);
  2687.         LineTo(rect.left + 1, rect.top + 1);
  2688.         
  2689.         //    • Set the inner corner pixel
  2690.         SetIfColor(dark);
  2691.         MoveTo(rect.left + 2, rect.top + 2);
  2692.         LineTo(rect.left + 2, rect.top + 2);
  2693.     }
  2694.     
  2695. } // T3DTextButtonAdorner::TopLeftCorner
  2696.  
  2697. //-------------------------------------------------------------------------------------
  2698. // T3DTextButtonAdorner::TopRightCorner
  2699. //-------------------------------------------------------------------------------------
  2700. #pragma segment A3DControlRes
  2701.  
  2702. pascal void T3DTextButtonAdorner::TopRightCorner (    const CRect& rect,
  2703.                                                                 const CRGBColor light,
  2704.                                                                 const CRGBColor dark,
  2705.                                                                 Boolean hilite )
  2706. {
  2707.     if (hilite)
  2708.     {
  2709.         //    • Set the outer corner pixel
  2710.         SetIfColor(dark);
  2711.         MoveTo(rect.right - 2, rect.top + 1);
  2712.         LineTo(rect.right - 2, rect.top + 1);
  2713.         
  2714.         //    • Set the inner corner pixel
  2715.         SetIfColor(light);
  2716.         MoveTo(rect.right - 3, rect.top + 2);
  2717.         LineTo(rect.right - 3, rect.top + 2);
  2718.     }
  2719.     else
  2720.     {
  2721.         //    • Set the outer corner pixel
  2722.         SetIfColor(light);
  2723.         MoveTo(rect.right - 2, rect.top + 1);
  2724.         LineTo(rect.right - 2, rect.top + 1);
  2725.         
  2726.         //    • Set the inner corner pixel
  2727.         SetIfColor(dark);
  2728.         MoveTo(rect.right - 3, rect.top + 2);
  2729.         LineTo(rect.right - 3, rect.top + 2);
  2730.     }
  2731.     
  2732. } // T3DTextButtonAdorner::TopRightCorner
  2733.  
  2734. //-------------------------------------------------------------------------------------
  2735. // T3DTextButtonAdorner::BotLeftCorner
  2736. //-------------------------------------------------------------------------------------
  2737. #pragma segment A3DControlRes
  2738.  
  2739. pascal void T3DTextButtonAdorner::BotLeftCorner (    const CRect& rect,
  2740.                                                                 const CRGBColor light,
  2741.                                                                 const CRGBColor dark,
  2742.                                                                 Boolean hilite )
  2743. {
  2744.     if (hilite)
  2745.     {
  2746.         //    • Set the outer corner pixel
  2747.         SetIfColor(dark);
  2748.         MoveTo(rect.left + 1, rect.bottom - 2);
  2749.         LineTo(rect.left + 1, rect.bottom - 2);
  2750.         
  2751.         //    • Set the inner corner pixel
  2752.         SetIfColor(light);
  2753.         MoveTo(rect.left + 2, rect.bottom - 3);
  2754.         LineTo(rect.left + 2, rect.bottom - 3);
  2755.     }
  2756.     else
  2757.     {
  2758.         //    • Set the outer corner pixel
  2759.         SetIfColor(light);
  2760.         MoveTo(rect.left + 1, rect.bottom - 2);
  2761.         LineTo(rect.left + 1, rect.bottom - 2);
  2762.         
  2763.         //    • Set the inner corner pixel
  2764.         SetIfColor(dark);
  2765.         MoveTo(rect.left + 2, rect.bottom - 3);
  2766.         LineTo(rect.left + 2, rect.bottom - 3);
  2767.     }
  2768. } // T3DTextButtonAdorner::BotLeftCorner
  2769.  
  2770. //-------------------------------------------------------------------------------------
  2771. // T3DTextButtonAdorner::BotRightCorner
  2772. //-------------------------------------------------------------------------------------
  2773. #pragma segment A3DControlRes
  2774.  
  2775. pascal void T3DTextButtonAdorner::BotRightCorner (const CRect& rect,
  2776.                                                             const CRGBColor light,
  2777.                                                             const CRGBColor dark,
  2778.                                                             Boolean hilite)
  2779. {
  2780.     if (hilite)
  2781.     {
  2782.         //    • Set the outer corner pixel
  2783.         SetIfColor(light);
  2784.         MoveTo(rect.right - 2, rect.bottom - 2);
  2785.         LineTo(rect.right - 2, rect.bottom - 2);
  2786.         
  2787.         //    • Set the inner corner pixel
  2788.         SetIfColor(dark);
  2789.         MoveTo(rect.right - 3, rect.bottom - 3);
  2790.         LineTo(rect.right - 3, rect.bottom - 3);
  2791.     }
  2792.     else
  2793.     {
  2794.         //    • Set the outer corner pixel
  2795.         SetIfColor(dark);
  2796.         MoveTo(rect.right - 2, rect.bottom - 2);
  2797.         LineTo(rect.right - 2, rect.bottom - 2);
  2798.         
  2799.         //    • Set the inner corner pixel
  2800.         SetIfColor(light);
  2801.         MoveTo(rect.right - 3, rect.bottom - 3);
  2802.         LineTo(rect.right - 3, rect.bottom - 3);
  2803.     }
  2804.     
  2805. } // T3DTextButtonAdorner::BotRightCorner
  2806.  
  2807.  
  2808.  
  2809. //===================================================================================== 
  2810. //    ••••••••••••••••• 3DIconButton class and auxiliary adorner ••••••••••••••••••••••••
  2811. //===================================================================================== 
  2812.  
  2813. //=====================================================================================
  2814. // T3DIconAdorner
  2815. //        This is an auxiliary adorner for T3DIconButtons
  2816. //=====================================================================================
  2817.  
  2818. //-------------------------------------------------------------------------------------
  2819. // T3DIconAdorner::I3DIconAdorner
  2820. //-------------------------------------------------------------------------------------
  2821. #pragma segment A3DControlOpen
  2822.  
  2823. pascal void T3DIconAdorner::I3DIconAdorner (    Boolean freeOnDeletion )
  2824. {
  2825.     //    • Call our superclass to complete initialization
  2826.     this->IAdorner ( k3DIconAdorner,freeOnDeletion );
  2827.     
  2828. } // T3DIconAdorner::I3DIconAdorner
  2829.  
  2830. //=====================================================================================
  2831. // •• DRAWING
  2832. //-------------------------------------------------------------------------------------
  2833. // T3DIconAdorner::Draw
  2834. //-------------------------------------------------------------------------------------
  2835. //
  2836. //    This overridden draw method handles the drawing of the buttons border and then
  2837. //    branches to the appropriate appropriate method to draw the buttons contents, based 
  2838. //    on the bit depth of the device being drawn to.  Currently this method supports 1, 4,
  2839. //    and 8 bit or more devices.
  2840.  
  2841. #pragma segment A3DControlRes
  2842.  
  2843. pascal void T3DIconAdorner::Draw (     TView* itsView, 
  2844.                                                 const VRect& /*area*/ )
  2845. {
  2846.  
  2847.     VRect                theRect;
  2848.     CRect                qdArea;
  2849.     short                pixelSize;
  2850.     
  2851.     //    • Instantiate a stack based object that saves our graphic state
  2852.     CGraphicsState aGraphicsState;
  2853.     
  2854.     //    •    Coerce the view to a control and then get its QD area
  2855.     TControl* theControl = (TControl*)itsView;    
  2856.     theControl->ControlArea ( theRect );
  2857.     theControl->ViewToQDRect ( theRect, qdArea );
  2858.         
  2859.     //    • Frame button with a black border that has a pixel missing in each corner
  2860.     //    this is drawn outside the while loop because it is always in black & white
  2861.     if (((TControl *)itsView)->IsDimmed())
  2862.         SetIfColor(kMediumGray);
  2863.     else
  2864.         SetIfColor ( gRGBBlack );
  2865.     this->Frame ( qdArea );
  2866.     
  2867.     //    • Inset the area in preparartion for the drawing of the buttons content
  2868.     InsetRect ( qdArea, 1, 1 );
  2869.         
  2870.     //    • Instantiate the stack based object that handles the per device clipping
  2871.     //    the area is passed in so that the object can do clipping from it
  2872.     if (((TControl *)itsView)->IsDimmed())
  2873.     {
  2874. //        Hack for non-CQD
  2875.         CDrawPerDevice device ( qdArea );
  2876.         while ( device.NextDevice ( pixelSize ) ) 
  2877.         {
  2878.             if ( pixelSize < 4 ) 
  2879.             {
  2880. //                Redraw the frame because it didn't draw if we're in non-CQD
  2881.                 CRect tempArea = qdArea;
  2882.                 CPenNormal();
  2883.                 InsetRect(tempArea, -1, -1);
  2884.                 this->Frame ( tempArea );
  2885.             }
  2886.         }
  2887.     }
  2888.     else
  2889.     {
  2890.         CDrawPerDevice device ( qdArea );
  2891.         
  2892.         //    • We will cycle through all of the devices, drawing will be handle based on
  2893.         //    the pixel size for each device
  2894.         while ( device.NextDevice ( pixelSize ) ) 
  2895.         {
  2896.             
  2897.             //    • Draw the button with full colors - there should really be two levels of 
  2898.             //    drawing here, one for 4 bit color and one for 8 bit.        
  2899.             if ( pixelSize >= 8 ) 
  2900.             {
  2901.                 
  2902.                 //    • Draw the button assuming 8 bit or better color
  2903.                 this->Draw8Bit ( qdArea, theControl->fHilite );
  2904.                 
  2905.             }
  2906.             else if ( pixelSize == 4 )    //    • Draw with only 16 colors
  2907.             {
  2908.             
  2909.                 //    • For now we will draw the 1 bit style for 4 bit, but this should be
  2910.                 //    replaced with a 4 bit algorithm which will give you 3 shades of gray
  2911.                 this->Draw4Bit ( qdArea, theControl->fHilite );
  2912.                 
  2913.             }            
  2914.             else if ( pixelSize < 4 )    //    • Draw with 4 colors or less (no grays)
  2915.             {
  2916.                 //    • Draw the 1 bit style for anything under 4 bit
  2917.                 this->Draw1Bit ( qdArea, theControl->fHilite );
  2918.                 
  2919.             }            
  2920.         }
  2921.     }
  2922.  
  2923. } // T3DIconAdorner::Draw
  2924.  
  2925.  
  2926. //=====================================================================================
  2927. // •• PRIVATE DRAWING
  2928. //-------------------------------------------------------------------------------------
  2929. // T3DIconAdorner::Draw8Bit
  2930. //-------------------------------------------------------------------------------------
  2931. #pragma segment A3DControlRes
  2932.  
  2933. pascal void T3DIconAdorner::Draw8Bit ( const CRect& rect,
  2934.                                                     Boolean hilite )
  2935. {
  2936.     CRect             insetArea;
  2937.     CRect             controlArea;
  2938.     CRGBColor         color;
  2939.     CRGBColor         light;
  2940.     CRGBColor         dark;
  2941.  
  2942.     //    • Make a copy of the rect passed in
  2943.     controlArea = rect;
  2944.     
  2945.     //    • Save off the area passed in
  2946.     insetArea = rect;
  2947.  
  2948.     //    • Draw the hilited button
  2949.     if ( hilite ) 
  2950.     {    
  2951.  
  2952.         //    • Outside edge of left top shadow
  2953.         SetRGBColor ( color, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  2954.         SetIfColor ( color );
  2955.         this->TopLeftSide ( controlArea );
  2956.  
  2957.         //    • Outside edge of bottom right shadow
  2958.         SetRGBColor ( color, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  2959.         SetIfColor ( color );
  2960.         this->BotRightSide ( controlArea );
  2961.         
  2962.         //    • Inset our rectangle as we move to the next level
  2963.         InsetRect ( controlArea, 1, 1 );
  2964.         
  2965.         //    • Inside edge of left top shadow
  2966.         SetRGBColor ( color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8 );
  2967.         SetIfColor ( color );
  2968.         this->TopLeftSide ( controlArea );
  2969.  
  2970.         //    • Inside edge of bottom right shadow
  2971.         color = kMediumLightGray;
  2972.         SetIfColor ( color );
  2973.         this->BotRightSide ( controlArea );    
  2974.         
  2975.         //    •• Now draw the corners 
  2976.         //    •    TopLeft 1
  2977.         SetRGBColor ( light, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  2978.         SetRGBColor ( dark, kRGB8BitGray10, kRGB8BitGray10, kRGB8BitGray10 );
  2979.         this->TopLeftCorner ( insetArea, light, dark );
  2980.         
  2981.         //    • TopRight 2
  2982.         light = kMediumGray;
  2983.         SetRGBColor ( dark, kRGB8BitGray7, kRGB8BitGray7, kRGB8BitGray7 );
  2984.         this->TopRightCorner ( insetArea, light, dark );
  2985.         
  2986.         //    • BotLeft 3
  2987.         //    • Colors same as previous corner
  2988.         this->BotLeftCorner ( insetArea, light, dark );
  2989.         
  2990.         //    • BotRight 4
  2991.         light = kLightGray2;
  2992.         SetRGBColor ( dark, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  2993.         this->BotRightCorner ( insetArea, light, dark, hilite );
  2994.         
  2995.         //    • Setup fill color for buttons face - hilite
  2996.         color = kMediumGray;
  2997.         
  2998.     }
  2999.     else //    • Draw the unhilited button
  3000.     {
  3001.         //    • Outside edge of left top shadow
  3002.         color = kLightGray2;
  3003.         SetIfColor ( color );
  3004.         this->TopLeftSide ( controlArea );
  3005.  
  3006.         //    • Outside edge of bottom right shadow
  3007.         SetRGBColor ( color, kRGB8BitGray7, kRGB8BitGray7, kRGB8BitGray7 );
  3008.         SetIfColor ( color );
  3009.         this->BotRightSide ( controlArea );
  3010.         
  3011.         //    • Inset our rectangle as we move to the next level
  3012.         InsetRect ( controlArea, 1, 1 );
  3013.         
  3014.         //    • Light on edge of button - light source edge
  3015.         SetIfColor ( gRGBWhite );
  3016.         this->TopLeftSide ( controlArea );
  3017.  
  3018.         //    • Inside edge of bottom right shadow
  3019.         color = kMediumGray;
  3020.         SetIfColor ( color );
  3021.         this->BotRightSide ( controlArea );    
  3022.         
  3023.         //    •• Now draw the corners 
  3024.         //    •    TopLeft 1
  3025.         this->TopLeftCorner ( insetArea, gRGBWhite, gRGBWhite );
  3026.         
  3027.         //    • TopRight 2
  3028.         SetRGBColor ( light, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  3029.         this->TopRightCorner ( insetArea, light, light );
  3030.         
  3031.         //    • BotLeft 3
  3032.         //    • Colors same as previous corner
  3033.         this->BotLeftCorner ( insetArea, light, light );
  3034.         
  3035.         //    • BotRight 4
  3036.         SetRGBColor ( light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8 );
  3037.         SetRGBColor ( dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  3038.         this->BotRightCorner ( insetArea, light, dark, hilite );
  3039.         
  3040.         //    • Setup fill color for button face
  3041.         color = kLightGray2;
  3042.         
  3043.     }
  3044.     
  3045.     //    • Inset our rectangle so that we can fill the rest of the area
  3046.     InsetRect ( controlArea, 1, 1 );
  3047.  
  3048.     //    • Now we will fill the rest of the button NOTE: color was setup at the
  3049.     //    end of either the hilite or normal draw routines
  3050.     SetIfColor ( color );
  3051.     PaintRect ( controlArea );
  3052.     
  3053. } // T3DIconAdorner::Draw8Bit
  3054.  
  3055.  
  3056. //-------------------------------------------------------------------------------------
  3057. // T3DIconAdorner::Draw4Bit
  3058. //-------------------------------------------------------------------------------------
  3059. #pragma segment A3DControlRes
  3060.  
  3061. pascal void T3DIconAdorner::Draw4Bit ( const CRect& rect,
  3062.                                                     Boolean hilite )
  3063. {
  3064.     CRect             insetArea;
  3065.     CRect             controlArea;
  3066.     CRGBColor         color;
  3067.     CRGBColor         light;
  3068.     CRGBColor         dark;
  3069.  
  3070.     //    • Make a copy of the rect passed in
  3071.     controlArea = rect;
  3072.     
  3073.     //    • Save off the area passed in
  3074.     insetArea = rect;
  3075.  
  3076.     //    • Draw the hilited button
  3077.     if ( hilite ) 
  3078.     {    
  3079.  
  3080.         //    • Outside edge of left top shadow
  3081.         SetRGBColor ( color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3082.         SetIfColor ( color );
  3083.         this->TopLeftSide ( controlArea );
  3084.  
  3085.         //    • Outside edge of bottom right shadow
  3086.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3087.         SetIfColor ( color );
  3088.         this->BotRightSide ( controlArea );
  3089.         
  3090.         //    • Inset our rectangle as we move to the next level
  3091.         InsetRect ( controlArea, 1, 1 );
  3092.         
  3093.         //    • Inside edge of left top shadow
  3094.         SetRGBColor ( color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3095.         SetIfColor ( color );
  3096.         this->TopLeftSide ( controlArea );
  3097.  
  3098.         //    • Inside edge of bottom right shadow
  3099.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3100.         SetIfColor ( color );
  3101.         this->BotRightSide ( controlArea );    
  3102.         
  3103.         //    •• Now draw the corners
  3104.         //    •    TopLeft 1
  3105.         SetRGBColor ( light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3106.         this->TopLeftCorner ( insetArea, light, light );
  3107.         
  3108.         //    • TopRight 2
  3109.         SetRGBColor ( light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3110.         this->TopRightCorner ( insetArea, light, light );
  3111.         
  3112.         //    • BotLeft 3
  3113.         SetRGBColor ( light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3114.         this->BotLeftCorner ( insetArea, light, light );
  3115.         
  3116.         //    • BotRight 4
  3117.         SetRGBColor ( light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3118.         this->BotRightCorner ( insetArea, light, light, hilite );
  3119.         
  3120.         //    • Setup fill color for button face - hilite
  3121.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3122.         
  3123.     }
  3124.     else //    • Draw the unhilited button
  3125.     {
  3126.         //    • Outside edge of left top shadow
  3127.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3128.         SetIfColor ( color );
  3129.         this->TopLeftSide ( controlArea );
  3130.  
  3131.         //    • Outside edge of bottom right shadow
  3132.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3133.         SetIfColor ( color );
  3134.         this->BotRightSide ( controlArea );
  3135.         
  3136.         //    • Inset our rectangle as we move to the next level
  3137.         InsetRect ( controlArea, 1, 1 );
  3138.         
  3139.         //    • Light on edge of button - light source edge
  3140.         SetIfColor ( gRGBWhite );
  3141.         this->TopLeftSide ( controlArea );
  3142.  
  3143.         //    • Inside edge of bottom right shadow
  3144.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3145.         SetIfColor ( color );
  3146.         this->BotRightSide ( controlArea );    
  3147.         
  3148.         //    •• Now draw the corners
  3149.         //    •    TopLeft 1
  3150.         this->TopLeftCorner ( insetArea, gRGBWhite, gRGBWhite );
  3151.         
  3152.         //    • TopRight 2
  3153.         SetRGBColor ( light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3154.         this->TopRightCorner ( insetArea, light, light );
  3155.         
  3156.         //    • BotLeft 3
  3157.         //    • Colors same as previous corner
  3158.         this->BotLeftCorner ( insetArea, light, light );
  3159.         
  3160.         //    • BotRight 4
  3161.         SetRGBColor ( light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3162.         this->BotRightCorner ( insetArea, light, light, hilite );
  3163.         
  3164.         //    • Setup fill color for button face
  3165.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3166.         
  3167.     }
  3168.     
  3169.     //    • Inset our rectangle so that we can fill the rest of the area
  3170.     InsetRect ( controlArea, 1, 1 );
  3171.  
  3172.     //    • Now we will fill the rest of the button NOTE: color was setup at the
  3173.     //    end of either the hilite or normal draw routines
  3174.     SetIfColor ( color );
  3175.     PaintRect ( controlArea );
  3176.     
  3177. } // T3DIconAdorner::Draw4Bit
  3178.  
  3179. //-------------------------------------------------------------------------------------
  3180. // T3DIconAdorner::Draw1Bit
  3181. //-------------------------------------------------------------------------------------
  3182. #pragma segment A3DControlRes
  3183.  
  3184. pascal void T3DIconAdorner::Draw1Bit ( const CRect& rect,
  3185.                                                     Boolean hilite )
  3186. {
  3187.     CRect insetArea;
  3188.     CRect controlArea;
  3189.  
  3190.     CPenNormal();
  3191.     
  3192.     //    • Make a copy of the rect passed in
  3193.     controlArea = rect;
  3194.     
  3195.     //    • Save off the area passed in
  3196.     insetArea = controlArea;
  3197.  
  3198.     //    • First we paint the inside white
  3199.     PenPat(&qd.white);
  3200.     ForeColor ( whiteColor );
  3201.     PaintRect ( controlArea );
  3202.     
  3203.     //    • Outside edge of bottom right shadow
  3204.     PenPat ( &qd.gray );
  3205.     ForeColor ( blackColor );
  3206.     this->BotRightSide ( controlArea );
  3207.     
  3208.     //    • Inset the rectangle again for the next level
  3209.     InsetRect ( controlArea, 1, 1 );
  3210.     
  3211.     //    • Inside edge of bottom right shadow
  3212.     this->BotRightSide ( controlArea );
  3213.  
  3214.     //    • We are hiliting so we need to invert the whole thing
  3215.     if  ( hilite ) 
  3216.         InvertRect ( insetArea );
  3217.  
  3218. } // T3DIconAdorner::Draw1Bit
  3219.  
  3220.  
  3221. //=====================================================================================
  3222. // •• BUTTON FRAME
  3223. //-------------------------------------------------------------------------------------
  3224. // T3DIconAdorner::Frame
  3225. //-------------------------------------------------------------------------------------
  3226. #pragma segment A3DControlRes
  3227.  
  3228. pascal void T3DIconAdorner::Frame ( const CRect& rect )
  3229. {
  3230.     //    •    Draw the frame around the button this never changes
  3231.     MoveTo ( rect.left, rect.bottom - 2 );
  3232.     LineTo ( rect.left, rect.top + 1 );
  3233.     MoveTo ( rect.left + 1, rect.top );
  3234.     LineTo ( rect.right - 2, rect.top );
  3235.     MoveTo ( rect.left + 1, rect.bottom - 1 );
  3236.     LineTo ( rect.right - 2, rect.bottom - 1 );
  3237.     MoveTo ( rect.right - 1, rect.bottom - 2 );
  3238.     LineTo ( rect.right - 1, rect.top + 1 );
  3239.  
  3240. } // T3DIconAdorner::Frame
  3241.  
  3242. //=====================================================================================
  3243. // •• EDGE DRAWING
  3244. //-------------------------------------------------------------------------------------
  3245. // T3DIconAdorner::TopLeftSide
  3246. //-------------------------------------------------------------------------------------
  3247. #pragma segment A3DControlRes
  3248.  
  3249. pascal void T3DIconAdorner::TopLeftSide ( const CRect& rect )
  3250. {
  3251.  
  3252.     MoveTo ( rect.left,rect.bottom-2 );
  3253.     LineTo ( rect.left,rect.top );
  3254.     LineTo ( rect.right-2,rect.top );
  3255.  
  3256. } // T3DIconAdorner::TopLeftSide
  3257.  
  3258. //-------------------------------------------------------------------------------------
  3259. // T3DIconAdorner::BotRightSide
  3260. //-------------------------------------------------------------------------------------
  3261. #pragma segment A3DControlRes
  3262.  
  3263. pascal void T3DIconAdorner::BotRightSide ( const CRect& rect )
  3264. {
  3265.  
  3266.     MoveTo ( rect.left,rect.bottom-1 );
  3267.     LineTo ( rect.right-1,rect.bottom-1 );
  3268.     LineTo ( rect.right-1,rect.top );
  3269.  
  3270. } // T3DIconAdorner::BotRightSide
  3271.  
  3272.  
  3273. //=====================================================================================
  3274. // •• CORNER DRAWING
  3275. //-------------------------------------------------------------------------------------
  3276. // T3DIconAdorner::TopLeftCorner
  3277. //-------------------------------------------------------------------------------------
  3278. #pragma segment A3DControlRes
  3279.  
  3280. pascal void T3DIconAdorner::TopLeftCorner (     const CRect& rect,
  3281.                                                             const CRGBColor light,
  3282.                                                             const CRGBColor dark  )
  3283. {
  3284.     //    • Set the outer corner pixel
  3285.     SetIfColor(dark);
  3286.     MoveTo(rect.left, rect.top);
  3287.     LineTo(rect.left, rect.top);
  3288.     
  3289.     //    • Set the inner corner pixel
  3290.     SetIfColor(light);
  3291.     MoveTo(rect.left + 1, rect.top + 1);
  3292.     LineTo(rect.left + 1, rect.top + 1);
  3293.     
  3294. } // T3DIconAdorner::TopLeftCorner
  3295.  
  3296. //-------------------------------------------------------------------------------------
  3297. // T3DIconAdorner::TopRightCorner
  3298. //-------------------------------------------------------------------------------------
  3299. #pragma segment A3DControlRes
  3300.  
  3301. pascal void T3DIconAdorner::TopRightCorner ( const CRect& rect,
  3302.                                                             const CRGBColor light,
  3303.                                                             const CRGBColor dark  )
  3304. {
  3305.     //    • Set the outer corner pixel
  3306.     SetIfColor(light);
  3307.     MoveTo(rect.right - 1, rect.top);
  3308.     LineTo(rect.right - 1, rect.top);
  3309.     
  3310.     //    • Set the inner corner pixel
  3311.     SetIfColor(dark);
  3312.     MoveTo(rect.right - 2, rect.top + 1);
  3313.     LineTo(rect.right - 2, rect.top + 1);
  3314.     
  3315. } // T3DIconAdorner::TopRightCorner
  3316.  
  3317. //-------------------------------------------------------------------------------------
  3318. // T3DIconAdorner::BotLeftCorner
  3319. //-------------------------------------------------------------------------------------
  3320. #pragma segment A3DControlRes
  3321.  
  3322. pascal void T3DIconAdorner::BotLeftCorner (     const CRect& rect,
  3323.                                                             const CRGBColor light,
  3324.                                                             const CRGBColor dark  )
  3325. {
  3326.     //    • Set the outer corner pixel
  3327.     SetIfColor(light);
  3328.     MoveTo(rect.left, rect.bottom - 1);
  3329.     LineTo(rect.left, rect.bottom - 1);
  3330.     
  3331.     //    • Set the inner corner pixel
  3332.     SetIfColor(dark);
  3333.     MoveTo(rect.left + 1, rect.bottom - 2);
  3334.     LineTo(rect.left + 1, rect.bottom - 2);
  3335.     
  3336. } // T3DIconAdorner::BotLeftCorner
  3337.  
  3338. //-------------------------------------------------------------------------------------
  3339. // T3DIconAdorner::BotRightCorner
  3340. //-------------------------------------------------------------------------------------
  3341. #pragma segment A3DControlRes
  3342.  
  3343. pascal void T3DIconAdorner::BotRightCorner ( const CRect& rect,
  3344.                                                             const CRGBColor light,
  3345.                                                             const CRGBColor dark,
  3346.                                                             Boolean hilite )
  3347. {
  3348.     if ( hilite )
  3349.     {
  3350.         //    • Set the outer corner pixel
  3351.         SetIfColor(light);
  3352.         MoveTo(rect.right - 1, rect.bottom - 1);
  3353.         LineTo(rect.right - 1, rect.bottom - 1);
  3354.         
  3355.         //    • Set the inner corner pixel
  3356.         SetIfColor(dark);
  3357.         MoveTo(rect.right - 2, rect.bottom - 2);
  3358.         LineTo(rect.right - 2, rect.bottom - 2);
  3359.     }
  3360.     else
  3361.     {
  3362.         //    • Set the outer corner pixel
  3363.         SetIfColor(dark);
  3364.         MoveTo(rect.right - 1, rect.bottom - 1);
  3365.         LineTo(rect.right - 1, rect.bottom - 1);
  3366.         
  3367.         //    • Set the inner corner pixel
  3368.         SetIfColor(light);
  3369.         MoveTo(rect.right - 2, rect.bottom - 2);
  3370.         LineTo(rect.right - 2, rect.bottom - 2);
  3371.     }
  3372.     
  3373. } // T3DIconAdorner::BotRightCorner
  3374.  
  3375.  
  3376. //=====================================================================================
  3377. // CLASS:    TIconSuite
  3378. //        The T3DIconButton class is based from this one.  However, you can use this
  3379. //        class alone if you wish.  It will draw an icon suite and allow you to
  3380. //        apply standard masks to respond to events
  3381. //=====================================================================================
  3382.  
  3383. //=====================================================================================
  3384. // •• INITIALIZATION & DISPOSAL
  3385. //-------------------------------------------------------------------------------------
  3386. // TIconSuite::Initialize
  3387. //-------------------------------------------------------------------------------------
  3388. #pragma segment    A3DControlOpen
  3389.  
  3390. pascal void TIconSuite::Initialize ()    // OVERRIDE
  3391. {
  3392.     inherited::Initialize ();
  3393.     
  3394.     fIconSuiteRsrcID = kNoResource;
  3395.     fAlignment = atNone;
  3396.     fDataHandle = NULL;
  3397.     fSelectorValue  = svAllAvailableData;
  3398.     
  3399. }    // TIconSuite::Initialize
  3400.  
  3401. //-------------------------------------------------------------------------------------
  3402. // TIconSuite::IIconSuite
  3403. //-------------------------------------------------------------------------------------
  3404. #pragma segment    A3DControlOpen
  3405.  
  3406. pascal void TIconSuite::IIconSuite (    TView* itsSuperView,
  3407.                                                     const VPoint& itsLocation,
  3408.                                                     const VPoint& itsSize,
  3409.                                                     SizeDeterminer itsHSizeDet,
  3410.                                                     SizeDeterminer itsVSizeDet,
  3411.                                                     ResNumber itsRsrcID,
  3412.                                                     IconAlignmentType    alignment,
  3413.                                                     IconSelectorValue selectorValue)
  3414. {
  3415.     FailInfo fi;
  3416.  
  3417.     this->IControl ( itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet );
  3418.     
  3419.     // • Setup our fields
  3420.     fAlignment = alignment;
  3421.     fEventNumber = mIconSuiteHit;                // We will use the mIconSuiteHit constant
  3422.  
  3423.     // • Installs the icon suite
  3424.     this->SetIconSuiteRsrcID ( itsRsrcID,selectorValue,kDontRedraw );
  3425.         
  3426.     // • Default is to enable hit testing
  3427.     this->SetEnable ( TRUE );                        
  3428.     
  3429. }    // TIconSuite::IIconSuite
  3430.  
  3431.  
  3432. //-------------------------------------------------------------------------------------
  3433. // TIconSuite::DoPostCreate
  3434. //-------------------------------------------------------------------------------------
  3435. #pragma segment    A3DControlOpen
  3436.  
  3437. pascal void TIconSuite::DoPostCreate(TDocument *itsDocument)
  3438. {
  3439.     inherited::DoPostCreate(itsDocument);
  3440.     
  3441.     fEventNumber = mIconSuiteHit;                // We will use the mIconSuiteHit constant
  3442.     fAlignment = atNone;
  3443.     
  3444.     // • Installs the icon suite - use the fUserArea field of the View resource
  3445.     //        as the icon suite
  3446.     this->SetIconSuiteRsrcID((short) fUserArea,svAllAvailableData,kDontRedraw);
  3447.         
  3448.     // • Default is to enable hit testing
  3449.     this->SetEnable ( TRUE );    
  3450. }
  3451.  
  3452.  
  3453. //-------------------------------------------------------------------------------------
  3454. // TIconSuite::Clone
  3455. //-------------------------------------------------------------------------------------
  3456. #pragma segment A3DControlNonRes
  3457.  
  3458. pascal TObject* TIconSuite::Clone ()    // OVERRIDE 
  3459. {
  3460.     TIconSuite* aClonedIconSuite;
  3461.     Handle itsRsrcHandle;
  3462.  
  3463.  
  3464.     // • First call inherited clone and coerce the result to our type
  3465.     aClonedIconSuite = ( TIconSuite* )( inherited::Clone ());
  3466.     
  3467.     // • Setup the cloned icon suite's fields
  3468.     aClonedIconSuite->fDataHandle = NULL;
  3469.     aClonedIconSuite->fAlignment = fAlignment;
  3470.     
  3471.     // • Now get a new copy of the resource handle and place it in the data field
  3472.     if ( fDataHandle )
  3473.     {
  3474.         // • Make the resource non-purgeable, so the Toolbox doesn't die 
  3475.         GetIconSuite ( &itsRsrcHandle, fIconSuiteRsrcID, fSelectorValue );
  3476.         
  3477.         aClonedIconSuite->fDataHandle = itsRsrcHandle;
  3478.         
  3479.         // • Check to see if it is a NIL resource
  3480.         FailNILResource ( aClonedIconSuite->fDataHandle );
  3481.             
  3482.     }
  3483.     
  3484.     // • Return the cloned icon suite
  3485.     return aClonedIconSuite;
  3486.     
  3487. }    //    TIconSuite::Clone
  3488.  
  3489. //-------------------------------------------------------------------------------------
  3490. // TIconSuite::Free
  3491. //-------------------------------------------------------------------------------------
  3492. #pragma segment A3DControlClose
  3493.  
  3494. pascal void TIconSuite::Free ()    // OVERRIDE 
  3495. {
  3496.  
  3497.     // • Get rid of the icon suite
  3498.     this->ReleaseIconSuite ();
  3499.  
  3500.     inherited::Free ();
  3501.  
  3502. }    // TIconSuite::Free
  3503.  
  3504.  
  3505. //-------------------------------------------------------------------------------------
  3506. // TIconSuite::ReleaseIconSuite
  3507. //-------------------------------------------------------------------------------------
  3508. #pragma segment A3DControlNonRes
  3509.  
  3510. pascal void TIconSuite::ReleaseIconSuite ()
  3511. {
  3512.     // • Set the rsrc ID field to nothing
  3513.     fIconSuiteRsrcID = kNoResource;
  3514.     
  3515.     // • If there is a data handle then dispose of the icon suite
  3516.     if ( fDataHandle )
  3517.     {
  3518.         OSErr    anError;
  3519.         
  3520.         anError = DisposeIconSuite ( fDataHandle, TRUE );
  3521.         fDataHandle = NULL;
  3522.     }
  3523.     
  3524. }    // TIconSuite::ReleaseIconSuite
  3525.  
  3526.  
  3527. //=====================================================================================
  3528. // •• ACCESSORS
  3529. //-------------------------------------------------------------------------------------
  3530. // TIconSuite::GetIconRect
  3531. //-------------------------------------------------------------------------------------
  3532. #pragma segment A3DControlRes
  3533.  
  3534. pascal void TIconSuite::GetIconRect ( VRect& theRect )
  3535. {
  3536.  
  3537.     this->ControlArea ( theRect );
  3538.     
  3539. }    // <- GetIconRect
  3540.  
  3541.  
  3542. //-------------------------------------------------------------------------------------
  3543. // TIconSuite::SetIconSuite
  3544. //-------------------------------------------------------------------------------------
  3545. #pragma segment A3DControlNonRes
  3546.  
  3547. pascal void TIconSuite::SetIconSuite ( Handle theSuite, Boolean redraw )
  3548. {
  3549.     ResNumber     theID;
  3550.     ResType         theType;
  3551.     CStr255         name;
  3552.  
  3553.     // • Release the existing icon suite and set the data field to
  3554.     // the new icon suite
  3555.     this->ReleaseIconSuite();
  3556.     fDataHandle = theSuite;
  3557.  
  3558.     // • Get the rsrc ID from the icon suite's handle 
  3559.     GetResInfo ( theSuite, theID, theType, name) ;
  3560.     if ( ResError() == noErr )
  3561.         fIconSuiteRsrcID = theID;
  3562.  
  3563.     // • Get everything redrawn so that the new icon can be displayed, if needed
  3564.     if ( redraw )
  3565.         this->ForceRedraw ();
  3566.         
  3567. }    // TIconSuite::SetIconSuite
  3568.  
  3569.  
  3570. //-------------------------------------------------------------------------------------
  3571. // TIconSuite::SetIconSuiteRsrcID
  3572. //-------------------------------------------------------------------------------------
  3573. #pragma segment A3DControlNonRes
  3574.  
  3575. pascal void TIconSuite::SetIconSuiteRsrcID ( short itsRsrcID, IconSelectorValue selectorValue, Boolean redraw )
  3576. {
  3577.     FailInfo     fi;
  3578.     Handle         itsRsrcHandle;
  3579.  
  3580.     if ( itsRsrcID != kNoResource )
  3581.     {    
  3582.         if (fi.Try())
  3583.         {
  3584.             // • Make the resource non-purgeable, so the Toolbox doesn't die 
  3585.             GetIconSuite ( &itsRsrcHandle, itsRsrcID, fSelectorValue );
  3586.             
  3587.             // • Check to see if it is a NIL resource
  3588.             FailNILResource ( itsRsrcHandle );
  3589.             
  3590.             // • Release the existing icon suite
  3591.             this->ReleaseIconSuite();
  3592.             
  3593.             // • Place the resource handle in our data field
  3594.             fDataHandle = itsRsrcHandle;
  3595.             fIconSuiteRsrcID = itsRsrcID;
  3596.             fSelectorValue = selectorValue;
  3597.             
  3598.             // • Hey! everything worked fine, we're out of here!!
  3599.             fi.Success ();
  3600.         }
  3601.         else    // Recover
  3602.         {
  3603.             fi.ReSignal ();
  3604.         }
  3605.  
  3606.     // • Get everything redrawn so that the new icon can be displayed, if needed
  3607.         if ( redraw )
  3608.             this->ForceRedraw ();
  3609.     
  3610.     }
  3611.         
  3612. }    // TIconSuite::SetIconSuiteRsrcID
  3613.  
  3614.  
  3615. //-------------------------------------------------------------------------------------
  3616. // TIconSuite::SetAlignment
  3617. //-------------------------------------------------------------------------------------
  3618. #pragma segment A3DControlNonRes
  3619.  
  3620. pascal void TIconSuite::SetAlignment ( IconAlignmentType newAlignment, Boolean redraw )
  3621. {
  3622.     // • Setup the field to the new alignment value
  3623.     fAlignment = newAlignment;
  3624.  
  3625.     // • Get everything redrawn so that the new icon can be displayed, if needed
  3626.     if ( redraw )
  3627.         this->ForceRedraw ();
  3628.         
  3629. }    // TIconSuite::SetAlignment
  3630.  
  3631.  
  3632. //=====================================================================================
  3633. // •• DRAWING
  3634. //-------------------------------------------------------------------------------------
  3635. // TIconSuite::Draw
  3636. //-------------------------------------------------------------------------------------
  3637. #pragma segment A3DControlRes
  3638.  
  3639. pascal void TIconSuite::Draw ( const VRect& area )    // OVERRIDE 
  3640. {
  3641.     // • Get the icon plotted with the "ttNone" transorm applied
  3642.     // this transform shows the icon in its normal state
  3643.     this->DoPlotIconSuite ( ttNone );
  3644.     
  3645.     inherited::Draw ( area );
  3646.  
  3647. }    // <- Draw
  3648.  
  3649.  
  3650. //-------------------------------------------------------------------------------------
  3651. // TIconSuite::DoPlotIconSuite    PRIVATE
  3652. //-------------------------------------------------------------------------------------
  3653. #pragma segment A3DControlRes
  3654.  
  3655. pascal void TIconSuite::DoPlotIconSuite ( IconTransformType transform )        // OVERRIDE 
  3656. {
  3657.     SignedByte oldState;
  3658.     VRect theRect;
  3659.     CRect theQDRect;
  3660.  
  3661.     // • We will only do something if we have a datahandle
  3662.     if ( fDataHandle )
  3663.     {
  3664.         // • If the data handle we have is a resource then make sure its loaded
  3665.         if ( IsAResource ( fDataHandle ))
  3666.             LoadResource ( fDataHandle );
  3667.             
  3668.         if ( *fDataHandle )                // If there's room for the icon… 
  3669.         {
  3670.             PenNormal();                        // NECESSARY? 
  3671.                     
  3672.             // • Get a Quickdraw rectangle of the control's extent
  3673.             this->GetIconRect ( theRect );
  3674.             this->ViewToQDRect ( theRect, theQDRect );
  3675.             
  3676.             // • Save off the state of the data handle
  3677.             oldState = HGetState ( fDataHandle );
  3678.             HNoPurge ( fDataHandle );
  3679.             HLock ( fDataHandle );
  3680.  
  3681.             // • Get the icon plotted using the transform passed in as
  3682.             // well as the current alignment
  3683.             PlotIconSuite ( &theQDRect, fAlignment, transform, fDataHandle);
  3684.  
  3685.             // • Restore the dtata handle's state
  3686.             HSetState ( fDataHandle, oldState );
  3687.         }
  3688.     }
  3689.     
  3690. }    // TIconSuite::DoPlotIconSuite
  3691.  
  3692.  
  3693. //=====================================================================================
  3694. // •• STATE
  3695. //-------------------------------------------------------------------------------------
  3696. // TIconSuite::Dim
  3697. //-------------------------------------------------------------------------------------
  3698. #pragma segment A3DControlRes
  3699.  
  3700. pascal void TIconSuite::Dim ()        // OVERRIDE 
  3701. {
  3702.  
  3703.     // • Plot the icon disabled if we are dimmed
  3704.     this->DoPlotIconSuite ( ttDisabled );
  3705.     
  3706. }    // TIconSuite::Dim
  3707.  
  3708.  
  3709. //-------------------------------------------------------------------------------------
  3710. // TIconSuite::Hilite
  3711. //-------------------------------------------------------------------------------------
  3712. #pragma segment A3DControlRes
  3713.  
  3714. pascal void TIconSuite::Hilite ()    // OVERRIDE
  3715. {
  3716.  
  3717.     // • If the icon is hilited then plot it "selected" otherwise plot is as 
  3718.     // normal in its unselected state
  3719.     if ( fHilite )
  3720.         this->DoPlotIconSuite ( ttSelected );
  3721.     else
  3722.         this->DoPlotIconSuite ( ttNone );
  3723.         
  3724. }    // TIconSuite::Hilite
  3725.  
  3726.  
  3727. //=====================================================================================
  3728. // CLASS:    T3DIconButton
  3729. //=====================================================================================
  3730.  
  3731. const    short    kDefaultSize    = 32;
  3732. //-------------------------------------------------------------------------------------
  3733. // T3DIconButton::Initialize
  3734. //-------------------------------------------------------------------------------------
  3735. #pragma segment A3DControlOpen
  3736.  
  3737. pascal void T3DIconButton::Initialize ()                // Override 
  3738. {
  3739.  
  3740.     inherited::Initialize ();
  3741.     
  3742.     f3DIconAdorner = NULL;
  3743.     fIconSize = kDefaultSize;        // Use 32x32 icons by default
  3744.     fMode = kButtonMode;            // Use button mode by default
  3745.     fState = FALSE;
  3746.     
  3747. } // T3DIconButton::Initialize
  3748.  
  3749. //-------------------------------------------------------------------------------------
  3750. // T3DIconButton::I3DButton
  3751. //-------------------------------------------------------------------------------------
  3752. #pragma segment A3DControlOpen
  3753.  
  3754. pascal void     T3DIconButton::I3DIconButton (    TView* itsSuperView,
  3755.                                                                         const VPoint& itsLocation,
  3756.                                                                         const VPoint& itsSize,
  3757.                                                                         SizeDeterminer itsHSizeDet,
  3758.                                                                         SizeDeterminer itsVSizeDet,
  3759.                                                                         short iconSize,
  3760.                                                                         ResNumber itsRsrcID,
  3761.                                                                         ButtonMode mode,
  3762.                                                                         Boolean state )
  3763. {
  3764.  
  3765.     IconSelectorValue selectorValue;
  3766.     
  3767.     switch ( iconSize ) 
  3768.     {
  3769.         case 12:
  3770.                 selectorValue = svAllMiniData;
  3771.             break;
  3772.         case 16:
  3773.                 selectorValue = svAllSmallData;
  3774.             break;
  3775.         case 32:
  3776.                 selectorValue = svAllLargeData;
  3777.             break;
  3778.     }
  3779.     
  3780.     //    • Get our superclass setup
  3781.     this->IIconSuite ( itsSuperView, itsLocation, itsSize,
  3782.                                         itsHSizeDet, itsVSizeDet,
  3783.                                             itsRsrcID, atAbsoluteCenter, selectorValue );
  3784.     
  3785.     fIconSize  = iconSize;
  3786.     this->SetMode ( mode );
  3787.     fState = state;
  3788.     fEventNumber = mIconButtonHit;
  3789.     
  3790.     //    • Get the correct hiliteState setup
  3791.     if ( fState )
  3792.         this->HiliteState ( fState, kRedraw );
  3793.     
  3794.     //    • If we are being built procedurally then build the adorner
  3795.     if ( f3DIconAdorner == NULL )
  3796.         this->CreateButtonAdorner ();
  3797.     
  3798. } // T3DIconButton::I3DButton
  3799.  
  3800. //-------------------------------------------------------------------------------------
  3801. // T3DIconButton::DoPostCreate
  3802. //-------------------------------------------------------------------------------------
  3803. #pragma segment A3DControlOpen
  3804.  
  3805. pascal void T3DIconButton::DoPostCreate ( TDocument *itsDocument ) // Override 
  3806. {
  3807.  
  3808.     inherited::DoPostCreate ( itsDocument );
  3809.  
  3810.     fEventNumber = mIconButtonHit;
  3811.     
  3812.     if ( f3DIconAdorner == NULL )
  3813.         this->CreateButtonAdorner ();
  3814.  
  3815. } // T3DIconButton::DoPostCreate
  3816.  
  3817. //-------------------------------------------------------------------------------------
  3818. // T3DIconButton::CreateButtonAdorner
  3819. //-------------------------------------------------------------------------------------
  3820. #pragma segment A3DControlOpen
  3821.  
  3822. pascal void T3DIconButton::CreateButtonAdorner ()
  3823. {
  3824.     
  3825.     // •    Add the 3D Button Adorner
  3826.     T3DIconAdorner* adorner = new T3DIconAdorner;
  3827.     adorner->I3DIconAdorner ( kFreeOnDeletion );
  3828.     f3DIconAdorner = adorner;
  3829.     this->AddAdorner ( adorner, kAdornFirst, kDontInvalidate );
  3830.  
  3831. } // T3DIconButton::CreateButtonAdorner
  3832.  
  3833. //-------------------------------------------------------------------------------------
  3834. // T3DIconButton::GetIconRect
  3835. //-------------------------------------------------------------------------------------
  3836. #pragma segment A3DControlRes
  3837.  
  3838. pascal void T3DIconButton::GetIconRect ( VRect& theRect )
  3839. {
  3840.  
  3841.     this->ControlArea ( theRect );
  3842.     
  3843.     VCoordinate iconSize = this->GetIconSize ( theRect.GetSize () );
  3844.     
  3845. //    Center the icon
  3846.     theRect.top += ( theRect.bottom - theRect.top - iconSize ) / 2;
  3847.     theRect.bottom = theRect.top + iconSize;
  3848.     theRect.left += ( theRect.right - theRect.left - iconSize ) / 2;
  3849.     theRect.right = theRect.left + iconSize;
  3850.  
  3851. }    //    T3DIconButton::GetIconRect
  3852.  
  3853. //-------------------------------------------------------------------------------------
  3854. // T3DIconButton::GetIconSize
  3855. //-------------------------------------------------------------------------------------
  3856. #pragma segment A3DControlNonRes
  3857.  
  3858. pascal short T3DIconButton::GetIconSize ( const VPoint& /*viewSize*/ )
  3859. {
  3860.  
  3861.     return fIconSize;
  3862.     
  3863. } // T3DIconButton::GetIconSize
  3864.  
  3865. //-------------------------------------------------------------------------------------
  3866. // T3DIconButton::Hilite
  3867. //-------------------------------------------------------------------------------------
  3868. #pragma segment A3DControlRes
  3869.  
  3870. pascal void T3DIconButton::Hilite ()        // Override
  3871. {
  3872.  
  3873.     VRect    area;
  3874.     this->GetExtent ( area) ;
  3875.     f3DIconAdorner->Draw ( this, area );
  3876.     
  3877.     inherited::Hilite ();
  3878.  
  3879. } // T3DIconButton::Hilite
  3880.  
  3881.  
  3882. //-------------------------------------------------------------------------------------
  3883. // T3DIconButton::Dim
  3884. //-------------------------------------------------------------------------------------
  3885. #pragma segment A3DControlRes
  3886.  
  3887. pascal void T3DIconButton::Dim ()        // Override
  3888. {
  3889.     inherited::Dim ();
  3890.  
  3891. } // T3DIconButton::Dim
  3892.  
  3893. //-------------------------------------------------------------------------------------
  3894. // T3DIconButton::SetIconSuite
  3895. //-------------------------------------------------------------------------------------
  3896. #pragma segment A3DControlNonRes
  3897.  
  3898. pascal void T3DIconButton::SetIconSuite ( Handle theSuite, 
  3899.                                                         Boolean redraw )
  3900. {
  3901.  
  3902.     inherited::SetIconSuite ( theSuite, redraw );
  3903.     
  3904.     this->SetAlignment ( atAbsoluteCenter, redraw );
  3905.  
  3906. } // T3DIconButton::SetIconSuite
  3907.  
  3908. //-------------------------------------------------------------------------------------
  3909. // T3DIconButton::SetIconSuiteRsrcID
  3910. //-------------------------------------------------------------------------------------
  3911. #pragma segment A3DControlNonRes
  3912.  
  3913. pascal void T3DIconButton::SetIconSuiteRsrcID ( short itsRsrcID, 
  3914.                                                                 IconSelectorValue selectorValue, 
  3915.                                                                 Boolean redraw )
  3916. {
  3917.  
  3918.     inherited::SetIconSuiteRsrcID ( itsRsrcID, selectorValue, redraw );
  3919.     this->SetAlignment ( atAbsoluteCenter,redraw );
  3920.     
  3921. } // T3DIconButton::SetIconSuiteRsrcID
  3922.  
  3923. //-------------------------------------------------------------------------------------
  3924. // T3DIconButton::SetIconRsrcID
  3925. //-------------------------------------------------------------------------------------
  3926. #pragma segment A3DControlNonRes
  3927.  
  3928. pascal void T3DIconButton::SetIconRsrcID ( short itsRsrcID, Boolean redraw )
  3929. {
  3930.  
  3931.     VRect theRect;
  3932.     IconSelectorValue selectorValue;
  3933.     
  3934.     this->ControlArea ( theRect );
  3935.     switch ( this->GetIconSize ( theRect.GetSize () ) ) 
  3936.     {
  3937.         case 12:
  3938.                 selectorValue = svAllMiniData;
  3939.             break;
  3940.         case 16:
  3941.                 selectorValue = svAllSmallData;
  3942.             break;
  3943.         case 32:
  3944.                 selectorValue = svAllLargeData;
  3945.             break;
  3946.     }
  3947.     
  3948.     this->SetIconSuiteRsrcID ( itsRsrcID, selectorValue, redraw );
  3949.  
  3950. } // T3DIconButton::SetIconRsrcID
  3951.  
  3952. //-------------------------------------------------------------------------------------
  3953. // T3DIconButton::SetMode
  3954. //-------------------------------------------------------------------------------------
  3955. #pragma    segment    A3DControlOpen
  3956.  
  3957. pascal void T3DIconButton::SetMode ( ButtonMode newMode )
  3958. {
  3959.             
  3960.     fMode = newMode;
  3961.     
  3962. }    // T3DIconButton::SetMode
  3963.  
  3964. //-------------------------------------------------------------------------------------
  3965. // T3DIconButton::GetMode
  3966. //-------------------------------------------------------------------------------------
  3967. #pragma    segment    A3DControlOpen
  3968.  
  3969. pascal ButtonMode T3DIconButton::GetMode ()
  3970. {
  3971.             
  3972.     return fMode;
  3973.     
  3974. }    // T3DIconButton::GetMode
  3975.  
  3976. //-------------------------------------------------------------------------------------
  3977. // T3DIconButton::IsSelected
  3978. //-------------------------------------------------------------------------------------
  3979. #pragma    segment    A3DControlNonRes
  3980.  
  3981. pascal Boolean T3DIconButton::IsSelected ( void )
  3982. {
  3983.             
  3984.     return fHilite;
  3985.     
  3986. }    // T3DIconButton::IsSelected
  3987.  
  3988. //-------------------------------------------------------------------------------------
  3989. // T3DIconButton::TrackMouse
  3990. //-------------------------------------------------------------------------------------
  3991. #pragma segment A3DControlSelCommand
  3992.  
  3993. pascal void T3DIconButton::TrackMouse (    TrackPhase aTrackPhase,
  3994.                                                              VPoint& ,
  3995.                                                              // anchorPoint
  3996.                                                              VPoint& ,
  3997.                                                              // previousPoint
  3998.                                                              VPoint& nextPoint,
  3999.                                                              Boolean )                            // OVERRIDE
  4000. {
  4001.     if (!this->IsDimmed())
  4002.         switch (aTrackPhase)
  4003.         {
  4004.             case trackBegin:
  4005.                 fState = fHilite;
  4006.                 this->HiliteState ( TRUE, kRedraw );
  4007.                 break;
  4008.             case trackContinue:
  4009.                 if (this->ContainsMouse ( nextPoint ))
  4010.                     this->HiliteState ( TRUE, kRedraw );
  4011.                 else
  4012.                     this->HiliteState ( fState, kRedraw);
  4013.                 break;
  4014.             case trackEnd:
  4015.                 if (this->ContainsMouse ( nextPoint ))
  4016.                 {
  4017.                     switch ( fMode )
  4018.                     {
  4019.                         case kButtonMode:
  4020.                             if ( fHilite )
  4021.                                 this->HiliteState ( FALSE, kRedraw);
  4022.                             break;
  4023.                         case kSwitchMode:
  4024.                             this->HiliteState ( !fHilite, kRedraw);
  4025.                             break;
  4026.                         case kRadioMode:
  4027.                             if ( !fHilite )
  4028.                                 this->HiliteState ( TRUE, kRedraw );
  4029.                             break;
  4030.                     }
  4031.                     
  4032.                     this->HandleEvent ( fEventNumber, this, NULL );
  4033.                 }
  4034.                 break;
  4035.         }
  4036. }    // T3DIconButton::TrackMouse
  4037.  
  4038.  
  4039.  
  4040.